module SnotelAPI

Constants

CLIENT
CSV_API_URL
VERSION
WSDL

Public Instance Methods

build_csv_api_url(station_triplets, hours_back) click to toggle source
# File lib/SnotelAPI.rb, line 119
def build_csv_api_url(station_triplets, hours_back)
  stations = station_triplets.join('|')
  url = "#{CSV_API_URL}#{CGI.escape(stations)}%7Cid%3D%22%22%7Cname~0/-#{hours_back}%2C0/stationId%2Cname%2CWTEQ%3A%3Avalue%2CSNWD%3A%3Avalue%2CTOBS%3A%3Avalue"
  return url
end
convert_raw_data_to_display_formats(data, hours_back) click to toggle source
# File lib/SnotelAPI.rb, line 125
def convert_raw_data_to_display_formats(data, hours_back)
  result = {}
  depth_data = []
  temperature_data = []
  sw_equivalent_data = []
  raw_data = []
  depth_counter = -hours_back
  temperature_counter = -hours_back
  sw_equivalent_counter = -hours_back
  data.each do |r|
    unless r[:snow_depth].nil?
      depth_data.append([depth_counter, r[:snow_depth].to_f])
    end
    depth_counter += 1
    unless r[:temp].nil?
      temperature_data.append([temperature_counter, r[:temp].to_f])
    end
    temperature_counter += 1
    unless r[:snow_water_equivalent].nil?
      sw_equivalent_data.append([sw_equivalent_counter, r[:snow_water_equivalent].to_f])
    end
    sw_equivalent_counter += 1
    raw_data.append([r[:datetime], r[:snow_water_equivalent].to_f, r[:snow_depth].to_f, r[:temp].to_f])
  end
  result[:depth_data] = depth_data
  result[:temperature_data] = temperature_data
  result[:sw_equivalent_data] = sw_equivalent_data
  result[:raw_data] = raw_data
  return result
end
csv_requirement(s) click to toggle source
# File lib/SnotelAPI.rb, line 105
def csv_requirement(s)
  comment = !/^#/.match(s).nil?
  comment || s.empty?
end
get_all_stations() click to toggle source
# File lib/SnotelAPI.rb, line 58
def get_all_stations
  make_wsdl_request(:get_stations, get_all_stations_xml)
end
get_all_stations_xml() click to toggle source
# File lib/SnotelAPI.rb, line 52
  def get_all_stations_xml
    <<-eos.strip_heredoc
      <networkCds>SNTL</networkCds>
      <logicalAnd>true</logicalAnd>
    eos
  end
get_bounded_stations(min_lat, max_lat, min_lon, max_lon) click to toggle source

Queries Snotel for any stations which are within min_lat, max_lat, min_lon, and max_lon This list is returned as an array of strings of the stations striplets

# File lib/SnotelAPI.rb, line 73
def get_bounded_stations(min_lat, max_lat, min_lon, max_lon)
  xml = make_wsdl_request(:get_stations, get_bounded_stations_xml(min_lat, max_lat, min_lon, max_lon))
  stations = xml.body[:get_stations_response][:return]
  unless stations.kind_of?(Array)
    stations = [stations]
  end
  return stations
end
get_bounded_stations_xml(min_lat, max_lat, min_lon, max_lon) click to toggle source
# File lib/SnotelAPI.rb, line 61
  def get_bounded_stations_xml(min_lat, max_lat, min_lon, max_lon)
    <<-eos.strip_heredoc
      <networkCds>SNTL</networkCds>
      <minLatitude>#{min_lat}</minLatitude>
      <maxLatitude>#{max_lat}</maxLatitude>
      <minLongitude>#{min_lon}</minLongitude>
      <maxLongitude>#{max_lon}</maxLongitude>
      <logicalAnd>true</logicalAnd>
    eos
  end
get_hourly_data(station_triplets, hours_back) click to toggle source
# File lib/SnotelAPI.rb, line 82
def get_hourly_data(station_triplets, hours_back)
  csv = make_csv_request(station_triplets, hours_back)
  return parse_hourly_data_csv(csv)
end
get_station_metadata(station_triplet) click to toggle source

Gets the stations metadata for the station_triplet The result is a hash of the values for the metadata Hash Values action_id, begin_date, county_name, elevation, end_date, fips_county_cd, fips_country_cd, fips_state_number huc, hud, latitude, longitude, name, shefid, station_data_time_zone, station_time_zone, station_triplet www.wcc.nrcs.usda.gov/web_service/AWDB_Web_Service_Reference.htm#StationMetadata

# File lib/SnotelAPI.rb, line 43
def get_station_metadata(station_triplet)
  xml = make_wsdl_request(:get_station_metadata, get_station_metadata_xml(station_triplet))
  xml.body[:get_station_metadata_response][:return]
end
get_station_metadata_xml(station_triplet) click to toggle source

Returns the xml for getting station metadata based on the station_triplet

# File lib/SnotelAPI.rb, line 48
def get_station_metadata_xml(station_triplet)
  "<stationTriplet>#{station_triplet}</stationTriplet>"
end
make_client(num=-1) click to toggle source
# File lib/SnotelAPI.rb, line 25
def make_client(num=-1)
  if num == -1
    return Savon::Client.new do
      wsdl 'lib/data/snotel-services.xml'
      log Rails.env.development?
    end
  end
  clients = ThreadSafe::Array.new(num)
  clients.map { make_client }
  return clients
end
make_csv_request(station_triplets, days_back) click to toggle source
# File lib/SnotelAPI.rb, line 110
def make_csv_request(station_triplets, days_back)
  url = URI.parse(build_csv_api_url(station_triplets, days_back))
  request = Net::HTTP::Get.new(url.to_s)
  response = Net::HTTP.start(url.host, url.port) do |http|
    http.request(request)
  end
  response.body
end
make_wsdl_request(method, message, client=nil) click to toggle source

Code docs here: www.wcc.nrcs.usda.gov/web_service/AWDB_Web_Service_Reference.htm#elementCodes Element Codes TOBS PREC SNWD WTEQ PRES DPTP RHUM SNOW WDIRV WDIR WSPD WSPV

# File lib/SnotelAPI.rb, line 18
def make_wsdl_request(method, message, client=nil)
  if client.nil?
    return CLIENT.call(method, message: message)
  end
  return client.call(method, message: message)
end
parse_hourly_data_csv(csv) click to toggle source
# File lib/SnotelAPI.rb, line 87
def parse_hourly_data_csv(csv)
  clean_csv = remove_csv_comments(csv)
  data = []
  clean_csv.each do |r|
    r = CSV.parse(r)[0]
    data.append({ datetime: r[0], snow_water_equivalent: r[3], snow_depth: r[4], temp: r[5] })
  end
  return data
end
remove_csv_comments(csv) click to toggle source

Takes in csv as a string. Parses it via newlines checking to see if any line is empty or contains a comment beggining with a #. Then shifts the csv to remove the header line of the file

# File lib/SnotelAPI.rb, line 99
def remove_csv_comments(csv)
  csv = csv.split(/\n/).reject { |s| csv_requirement(s) }
  csv.shift()
  return csv
end