Difference between revisions of "NOAA Weather"
From LinuxMCE
m |
|||
(9 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | + | {| align="right" | |
+ | | __TOC__ | ||
+ | |} | ||
+ | This device retrieves weather data from weather.gov. Using an ICAO identifier for a nearby airport, the weather data should be fairly accurate for your area. Not quite as good or up to date as a weather station in your back yard, it does a decent job. Keep in mind the data is only updated once per hour at 15 past. | ||
− | + | =How to setup the NOAA Weather GSD= | |
− | =Device Template= | + | ==Device Template== |
* Description - NOAA Weather | * Description - NOAA Weather | ||
* Implements DCE | * Implements DCE | ||
Line 8: | Line 11: | ||
* Comm Method - Ethernet | * Comm Method - Ethernet | ||
* Commands - Ruby internal commands | * Commands - Ruby internal commands | ||
− | + | ==GSD Code== | |
− | + | ===New Climate Commands=== | |
− | =GSD Code= | + | These are added under '''[[LinuxMCE Admin Website]]-->Advanced->DCE->[[Commands]]''' |
− | + | ====#923 Get Humidity==== | |
+ | <pre> | ||
+ | get_weather_data_request("Humidity") | ||
+ | </pre> | ||
+ | ====#921 Get Temperature==== | ||
+ | <pre> | ||
+ | get_weather_data_request("Temperature") | ||
+ | </pre> | ||
+ | ====#922 Get Weather==== | ||
+ | <pre> | ||
+ | get_weather_data_request("Weather") | ||
+ | </pre> | ||
+ | ==== #395 Check for updates==== | ||
<pre> | <pre> | ||
check_weather() | check_weather() | ||
</pre> | </pre> | ||
− | + | ====#396 Check for updates done==== | |
− | + | ||
<pre> | <pre> | ||
check_weather_done() | check_weather_done() | ||
</pre> | </pre> | ||
− | + | ====#373 Private Method Listing==== | |
− | + | ||
<pre> | <pre> | ||
### Logging function | ### Logging function | ||
def log(word) | def log(word) | ||
− | $logFile.print( word + "\n" ) | + | $logFile.print( Time.now.to_s + " " + word + "\n" ) |
$logFile.flush() | $logFile.flush() | ||
end | end | ||
Line 45: | Line 58: | ||
### Get xml file from NOAA | ### Get xml file from NOAA | ||
− | # | + | # xmlPath = "www.weather.gov/xml/current_obs/"+$identifier+".xml" |
− | # | + | # h = "GET "+xmlPath+" HTTP/1.0\r\n" |
− | # | + | # log("HTTP Request: #{h}") |
− | # | + | # conn_.Send(h) |
− | # | + | # resv = "" |
− | # | + | # while(true) |
− | # | + | # buff = conn_.Recv(16384, 5000) |
− | # | + | # if buff.length() == 0 |
− | # | + | # break |
− | # | + | # end |
− | # | + | # recv = recv + buff |
− | # | + | # end |
h = Net::HTTP.new('www.weather.gov', 80) | h = Net::HTTP.new('www.weather.gov', 80) | ||
− | data_loc = "/ | + | data_loc = "/xml/current_obs/"+$identifier+".xml" |
resp, data = h.get(data_loc, nil) | resp, data = h.get(data_loc, nil) | ||
if resp.message == "OK" | if resp.message == "OK" | ||
− | # | + | # if recv =~ /^HTTP[^\r\n]+200\sOK.+?\r\n\r\n(.+)$/m |
− | # | + | # data = $1 |
− | # | + | # log("Recieved:\n#{data}") |
− | + | ||
data.each_line {|line| | data.each_line {|line| | ||
if line =~/location>(.*)<\/location>/ | if line =~/location>(.*)<\/location>/ | ||
Line 126: | Line 139: | ||
ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 75 13 \""+$weather+"\"" | ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 75 13 \""+$weather+"\"" | ||
system(ms) | system(ms) | ||
− | log(" | + | log("Sent: #{ms}") |
end | end | ||
if $temp != oldtemp | if $temp != oldtemp | ||
ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 25 13 \""+$temp+"\"" | ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 25 13 \""+$temp+"\"" | ||
system(ms) | system(ms) | ||
− | log(" | + | log("Sent: #{ms}") |
+ | end | ||
+ | if $humidity != oldhumidity | ||
+ | ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 26 13 \""+$humidity+"\"" | ||
+ | system(ms) | ||
+ | log("Sent: #{ms}") | ||
end | end | ||
− | |||
check_weather_done() | check_weather_done() | ||
end | end | ||
Line 142: | Line 159: | ||
log("Weather check complete") | log("Weather check complete") | ||
end | end | ||
− | |||
− | + | ### Requests for weather data | |
+ | def get_weather_data_request(request) | ||
+ | case request | ||
+ | when "Temperature" | ||
+ | log('Recieved: Get Temperature request') | ||
+ | ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 76 13 \""+$temp+"\"" | ||
+ | system(ms) | ||
+ | log("Sent: #{ms}") | ||
+ | when "Weather" | ||
+ | log('Recieved: Get Weather request') | ||
+ | ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 77 13 \""+$weather+"\"" | ||
+ | system(ms) | ||
+ | log("Sent: #{ms}") | ||
+ | when "Humidity" | ||
+ | log('Recieved: Get Humidity request') | ||
+ | ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 78 13 \""+$humidity+"\"" | ||
+ | system(ms) | ||
+ | log("Sent: #{ms}") | ||
+ | end | ||
+ | end | ||
+ | ====#351 Process IDLE==== | ||
<pre> | <pre> | ||
### Auto check weather every quarter past the hour per NOAA | ### Auto check weather every quarter past the hour per NOAA | ||
t = Time.now | t = Time.now | ||
− | |||
− | * #355 Process Initialize | + | if t.min == 15 |
+ | t -= (60 * 60) | ||
+ | |||
+ | if $obs_time =~/(\d\d):\d\d:\d\d/ | ||
+ | obs_hour = $1 | ||
+ | end | ||
+ | |||
+ | if t.hour != obs_hour.to_i | ||
+ | log("Quarter past the hour and weather update needed") | ||
+ | check_weather() | ||
+ | end | ||
+ | end | ||
+ | </pre> | ||
+ | ====#355 Process Initialize==== | ||
<pre> | <pre> | ||
### | ### | ||
Line 234: | Line 282: | ||
</pre> | </pre> | ||
− | + | ====#356 Process Release==== | |
<pre> | <pre> | ||
if ($logFile != nil) then | if ($logFile != nil) then | ||
Line 240: | Line 288: | ||
end | end | ||
</pre> | </pre> | ||
− | + | ==Device Data== | |
− | + | (These variable numbers may be different, be sure to update them in the ruby code) | |
− | =Device Data= | + | |
* #249 ICAO Location Indicator(string) - Comment: Local airport identifier for weather info - (Required and Allowed to modify checked) | * #249 ICAO Location Indicator(string) - Comment: Local airport identifier for weather info - (Required and Allowed to modify checked) | ||
* #250 Units(string) - Comment: Degree units. Either (F) or (C) - (Required and Allowed to modify checked) | * #250 Units(string) - Comment: Degree units. Either (F) or (C) - (Required and Allowed to modify checked) | ||
− | + | ==Commands device responds to== | |
− | + | * Get Humidity #923 | |
− | =Events= | + | * Get Temperature #921 |
− | * Temperature Changed #25 - | + | * Get Weather #922 |
− | * Weather Changed #75 - | + | ==Events Sent by Device== |
− | + | * Temperature Changed #25 - Temperature has changed since last update | |
− | + | * Weather Changed #75 - Weather has changed since last update | |
− | =Issues and TODO= | + | * Humidity Changed #26 - Humidity has changed since last update |
− | * Does not respond to events | + | ==New climate events== |
− | * Only send weather info when there is a change from the previous weather check | + | (Need to be added, I had to put them directly into the db since the admin interface would not) |
− | * No way to ask for weather data from the device | + | * Get Temperature Response #76 - Response for Get Temperature command |
+ | * Get Weather Response #77 - Response for Get Weather command | ||
+ | * Get Humidity Response #78 - Response for Get Humidity command | ||
+ | ==Issues and TODO== | ||
+ | * 2008-07-06 Testing new features. | ||
+ | * 2008-07-26 Updated code with new features | ||
+ | * Fixed weather.gov xml url | ||
+ | * Does not respond to events (Added) | ||
+ | * Only send weather info when there is a change from the previous weather check (Done) | ||
+ | * Only sends weather conditions and temperature changes (Added humidity) | ||
+ | * No way to ask for weather data from the device (Done) | ||
+ | [[category: Tutorials]] | ||
+ | [[Category: Climate ]] |
Latest revision as of 17:21, 31 August 2012
This device retrieves weather data from weather.gov. Using an ICAO identifier for a nearby airport, the weather data should be fairly accurate for your area. Not quite as good or up to date as a weather station in your back yard, it does a decent job. Keep in mind the data is only updated once per hour at 15 past.
How to setup the NOAA Weather GSD
Device Template
- Description - NOAA Weather
- Implements DCE
- Device Category - Environment Climate Device #83
- Comm Method - Ethernet
- Commands - Ruby internal commands
GSD Code
New Climate Commands
These are added under LinuxMCE Admin Website-->Advanced->DCE->Commands
#923 Get Humidity
get_weather_data_request("Humidity")
#921 Get Temperature
get_weather_data_request("Temperature")
#922 Get Weather
get_weather_data_request("Weather")
#395 Check for updates
check_weather()
#396 Check for updates done
check_weather_done()
#373 Private Method Listing
### Logging function def log(word) $logFile.print( Time.now.to_s + " " + word + "\n" ) $logFile.flush() end ### Weather check function def check_weather() log("Backing up previous data") oldweather = $weather oldtemp = $temp oldpressure = $pressure olddew_point = $dew_point oldheat_index = $heat_index oldwindchill = $windchill oldhumidity = $humidity oldwind = $wind oldvisibility = $visibility log("Checking for weather updates") ### Get xml file from NOAA # xmlPath = "www.weather.gov/xml/current_obs/"+$identifier+".xml" # h = "GET "+xmlPath+" HTTP/1.0\r\n" # log("HTTP Request: #{h}") # conn_.Send(h) # resv = "" # while(true) # buff = conn_.Recv(16384, 5000) # if buff.length() == 0 # break # end # recv = recv + buff # end h = Net::HTTP.new('www.weather.gov', 80) data_loc = "/xml/current_obs/"+$identifier+".xml" resp, data = h.get(data_loc, nil) if resp.message == "OK" # if recv =~ /^HTTP[^\r\n]+200\sOK.+?\r\n\r\n(.+)$/m # data = $1 # log("Recieved:\n#{data}") data.each_line {|line| if line =~/location>(.*)<\/location>/ $location = $1 end if line =~/observation_time_rfc822>(.*)<\/observation_time_rfc822>/ $obs_time = $1 end if line =~/weather>(.*)<\/weather>/ $weather = $1 end if $units == "F" if line =~/temp_f>(.*)<\/temp_f>/ $temp = $1 end if line =~/pressure_in>(.*)<\/pressure_in>/ $pressure = $1 end if line =~/dewpoint_f>(.*)<\/dewpoint_f>/ $dew_point = $1 end if line =~/heat_index_f>(.*)<\/heat_index_f>/ $heat_index = $1 end if line =~/windchill_f>(.*)<\/windchill_f>/ $windchill = $1 end else if line =~/temp_c>(.*)<\/temp_c>/ $temp = $1 end if line =~/pressure_mb>(.*)<\/pressure_mb>/ $pressure = $1 end if line =~/dewpoint_c>(.*)<\/dewpoint_c>/ $dew_point = $1 end if line =~/heat_index_c>(.*)<\/heat_index_c>/ $heat_index = $1 end if line =~/windchill_c>(.*)<\/windchill_c>/ $windchill = $1 end end if line =~/relative_humidity>(.*)<\/relative_humidity>/ $humidity = $1 end if line =~/wind_string>(.*)<\/wind_string>/ $wind = $1 end if line =~/visibility_mi>(.*)<\/visibility_mi>/ $visibility = $1 end } end ### Send out events for weather changes if $weather != oldweather ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 75 13 \""+$weather+"\"" system(ms) log("Sent: #{ms}") end if $temp != oldtemp ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 25 13 \""+$temp+"\"" system(ms) log("Sent: #{ms}") end if $humidity != oldhumidity ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 26 13 \""+$humidity+"\"" system(ms) log("Sent: #{ms}") end check_weather_done() end ### Post weather check def check_weather_done() log("Weather data from: "+$obs_time) log("Weather check complete") end ### Requests for weather data def get_weather_data_request(request) case request when "Temperature" log('Recieved: Get Temperature request') ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 76 13 \""+$temp+"\"" system(ms) log("Sent: #{ms}") when "Weather" log('Recieved: Get Weather request') ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 77 13 \""+$weather+"\"" system(ms) log("Sent: #{ms}") when "Humidity" log('Recieved: Get Humidity request') ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 78 13 \""+$humidity+"\"" system(ms) log("Sent: #{ms}") end end ====#351 Process IDLE==== <pre> ### Auto check weather every quarter past the hour per NOAA t = Time.now if t.min == 15 t -= (60 * 60) if $obs_time =~/(\d\d):\d\d:\d\d/ obs_hour = $1 end if t.hour != obs_hour.to_i log("Quarter past the hour and weather update needed") check_weather() end end
#355 Process Initialize
### # NOAA Weather check # 2008 Jason Speckman ### require 'net/http' # Init Vars $logFile = File.new("/var/log/pluto/NOAA_Weather.log", "w") ### Change these values to match device data values $DEVICEDATA_ICAO_CONST = 249 $DEVICEDATA_UNITS_CONST = 250 $units = "" $identifier = "" $location = "" $obs_time = "" $weather = "" $temp = "" $pressure = "" $dew_point = "" $heat_index = "" $windchill = "" $humidity = "" $wind = "" $visibility = "" ### Check for identifier and units if device_.devdata_ != nil if device_.devdata_[$DEVICEDATA_ICAO_CONST] != nil $identifier = device_.devdata_[$DEVICEDATA_ICAO_CONST] log("ICAO identifier: "+$identifier) else log("No ICAO identifier specified") end if device_.devdata_[$DEVICEDATA_UNITS_CONST] != nil $units = device_.devdata_[$DEVICEDATA_UNITS_CONST] else $units = "F" end end log("Units in degrees "+$units) if $units == "F" $press_units = "in. Hg" else $press_units = "hPa" end ### Tell DCE we are a climate device log("Starting NOAA Weather Check") log("Setup message intercept for DCERouter") ### # devIDfrom: device_.devid_ = my device id # devIDto: -1000 = dcerouter # priority: # type: 1 = command, 2 = event # id: $devIDfrom = device_.devid_ devIDto = -1000 priority = "" type = 2 id = "" #cmd = Command.new(devIDfrom, devIDto, priority, type, id) #cmd.params_[x] = y #SendCommand(cmd) #ms = "/usr/pluto/bin/MessageSend dcerouter " + device_.devid_.to_s + " -1000 8 0 5 2 4 10" #system(ms) log("Init complete") ### Initial weather check check_weather()
#356 Process Release
if ($logFile != nil) then $logFile.close end
Device Data
(These variable numbers may be different, be sure to update them in the ruby code)
- #249 ICAO Location Indicator(string) - Comment: Local airport identifier for weather info - (Required and Allowed to modify checked)
- #250 Units(string) - Comment: Degree units. Either (F) or (C) - (Required and Allowed to modify checked)
Commands device responds to
- Get Humidity #923
- Get Temperature #921
- Get Weather #922
Events Sent by Device
- Temperature Changed #25 - Temperature has changed since last update
- Weather Changed #75 - Weather has changed since last update
- Humidity Changed #26 - Humidity has changed since last update
New climate events
(Need to be added, I had to put them directly into the db since the admin interface would not)
- Get Temperature Response #76 - Response for Get Temperature command
- Get Weather Response #77 - Response for Get Weather command
- Get Humidity Response #78 - Response for Get Humidity command
Issues and TODO
- 2008-07-06 Testing new features.
- 2008-07-26 Updated code with new features
- Fixed weather.gov xml url
- Does not respond to events (Added)
- Only send weather info when there is a change from the previous weather check (Done)
- Only sends weather conditions and temperature changes (Added humidity)
- No way to ask for weather data from the device (Done)