Jump to content

NOAA Weather: Difference between revisions

From LinuxMCE
Jspeckman (talk | contribs)
No edit summary
Jspeckman (talk | contribs)
No edit summary
Line 1: Line 1:
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'''
'''How to setup the NOAA Weather GSD'''



Revision as of 00:24, 9 July 2008

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

  • #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( 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/data/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 = "/data/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("Message sent: #{ms}")
  end
  if $temp != oldtemp
    ms = "/usr/pluto/bin/MessageSend dcerouter "+device_.devid_.to_s+" -1001 2 25 13 \""+$temp+"\""
    system(ms)
    log("Message 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
  • #351 Process IDLE
### 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)


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

  • 2008-07-06 Testing new features. Code will be updated soon.
  • Does not respond to events (currently testing new feature)
  • Only send weather info when there is a change from the previous weather check (currently testing new feature)
  • Only sends weather conditions and temperature changes (testing humidity changes)
  • No way to ask for weather data from the device (currently testing)