Difference between revisions of "NOAA Weather"

From LinuxMCE
Jump to: navigation, search
m
m
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
'''How to setup the NOAA Weather GSD'''
+
{| 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]]'''
* #395 Check for updates
+
====#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====
* #396 Check for updates done
+
 
<pre>
 
<pre>
 
check_weather_done()
 
check_weather_done()
 
</pre>
 
</pre>
 
+
====#373 Private Method Listing====
* #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/data/current_obs/"+$identifier+".xml"
+
# xmlPath = "www.weather.gov/xml/current_obs/"+$identifier+".xml"
# h = "GET "+xmlPath+" HTTP/1.0\r\n"
+
# h = "GET "+xmlPath+" HTTP/1.0\r\n"
# log("HTTP Request: #{h}")
+
# log("HTTP Request: #{h}")
# conn_.Send(h)
+
# conn_.Send(h)
# resv = ""
+
# resv = ""
# while(true)
+
# while(true)
#   buff = conn_.Recv(16384, 5000)
+
# buff = conn_.Recv(16384, 5000)
#   if buff.length() == 0
+
# if buff.length() == 0
#     break
+
# break
#   end
+
# end
#   recv = recv + buff
+
# recv = recv + buff
# end
+
# end
 
   h = Net::HTTP.new('www.weather.gov', 80)
 
   h = Net::HTTP.new('www.weather.gov', 80)
   data_loc = "/data/current_obs/"+$identifier+".xml"
+
   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
+
# if recv =~ /^HTTP[^\r\n]+200\sOK.+?\r\n\r\n(.+)$/m
#   data = $1
+
# data = $1
#   log("Recieved:\n#{data}")
+
# 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("Message sent: #{ms}")
+
     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("Message sent: #{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
 
   end
 
 
   check_weather_done()
 
   check_weather_done()
 
end
 
end
Line 142: Line 159:
 
   log("Weather check complete")
 
   log("Weather check complete")
 
end
 
end
</pre>
 
  
* #351 Process IDLE
+
### 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
Line 162: Line 198:
 
end
 
end
 
</pre>
 
</pre>
 
+
====#355 Process Initialize====
* #355 Process Initialize
+
 
<pre>
 
<pre>
 
###
 
###
Line 247: Line 282:
 
</pre>
 
</pre>
  
* #356 Process Release
+
====#356 Process Release====
 
<pre>
 
<pre>
 
if ($logFile != nil) then
 
if ($logFile != nil) then
Line 253: Line 288:
 
end
 
end
 
</pre>
 
</pre>
 
+
==Device Data==
 
+
=Device Data=
+
 
(These variable numbers may be different, be sure to update them in the ruby code)
 
(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)
 
* #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 - Comment: Temperature has changed since last update
+
* Get Weather #922
* Weather Changed #75 - Comment: Weather has changed since last update
+
==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)
* Only sends weather conditions and temperature changes
+
* Get Temperature Response #76 - Response for Get Temperature command
* No way to ask for weather data from the device
+
* Get Weather Response #77 - Response for Get Weather command
 
+
* Get Humidity Response #78 - Response for Get Humidity command
 
+
==Issues and TODO==
[[category: tutorials]]
+
* 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)