class Lita::Handlers::OnewheelAqi

Constants

REDIS_KEY

Public Instance Methods

aqi_irc_emoji() click to toggle source
# File lib/lita/handlers/onewheel_aqi.rb, line 83
def aqi_irc_emoji
  { 0..50 => '🌳',
    51..100 => '⚠️',
    101..150 => '🔶',
    151..200 => '🚫',
    201..300 => '☣️',
    301..999 => '🚫☣🚫' }
end
aqi_range_colors() click to toggle source

Based on the temp in F.

# File lib/lita/handlers/onewheel_aqi.rb, line 56
def aqi_range_colors
  { 0..50 => :green,
    51..100 => :yellow,
    101..150 => :orange,
    151..200 => :red,
    201..300 => :purple,
    301..999 => :pink }
end
aqi_range_labels() click to toggle source
# File lib/lita/handlers/onewheel_aqi.rb, line 65
def aqi_range_labels
  { 0..50 => 'Good',
    51..100 => 'Moderate',
    101..150 => 'Unhealthy for Sensitive Groups',
    151..200 => 'Unhealthy for All',
    201..300 => 'Very Unhealthy',
    301..999 => 'Hazardous' }
end
aqi_slack_emoji() click to toggle source
# File lib/lita/handlers/onewheel_aqi.rb, line 74
def aqi_slack_emoji
  { 0..50 => ':deciduous_tree:',
    51..100 => ':warning:',
    101..150 => ':large_orange_diamond:',
    151..200 => ':no_entry_sign:',
    201..300 => ':radioactive_sign:',
    301..999 => ':no_entry_sign: :radioactive_sign: :no_entry_sign:' }
end
color_str(str, value = nil) click to toggle source
# File lib/lita/handlers/onewheel_aqi.rb, line 238
def color_str(str, value = nil)
  value = str.to_i if value.nil?

  aqi_range_colors.keys.each do |color_key|
    next unless color_key.cover? value # Super secred cover sauce
    if config.mode == :irc
      color = colors[aqi_range_colors[color_key]]
      str = "\x03#{color}#{str}\x03"
    end
  end

  str
end
color_str_with_value(range_str:, range_value:) click to toggle source
# File lib/lita/handlers/onewheel_aqi.rb, line 252
def color_str_with_value(range_str:, range_value:)
  str = nil
  aqi_range_colors.keys.each do |color_key|
    next unless color_key.cover? range_value.to_i # Super secred cover sauce
    color = colors[aqi_range_colors[color_key]]
    if config.mode == :irc
      str = "#{aqi_irc_emoji[color_key]} \x03#{color}#{range_str[color_key]}\x03 #{aqi_irc_emoji[color_key]} "
    elsif config.mode == :slack
      str = "#{aqi_slack_emoji[color_key]} #{range_str[color_key]} #{aqi_slack_emoji[color_key]} "
    end
  end

  str
end
colors() click to toggle source

IRC colors.

# File lib/lita/handlers/onewheel_aqi.rb, line 36
def colors
  { white:  '00',
    black:  '01',
    blue:   '02',
    green:  '03',
    red:    '04',
    brown:  '05',
    purple: '06',
    orange: '07',
    yellow: '08',
    lime:   '09',
    teal:   '10',
    aqua:   '11',
    royal:  '12',
    pink:   '13',
    grey:   '14',
    silver: '15' }
end
get_aqi(response) click to toggle source
# File lib/lita/handlers/onewheel_aqi.rb, line 148
def get_aqi(response)
  loc = get_location(response)
  aqi = get_observed_aqi(loc)

  if aqi['status'] == 'nug'
    Lita.logger.info "Status is 'nug' for aqi station near #{loc['name']}"
    aqi = get_observed_aqi(loc)
  end

  if aqi['status'] == 'nug'
    response.reply "Reply hazy, try again."
    return
  end

  banner_str = '' #"(#{aqi['data']['city']['url']})"

  reply = "AQI for #{loc[:name]}, "

  Lita.logger.debug "Config mode: #{config.mode.inspect}"

  if config.mode == :irc
    reply += color_str_with_value(range_str: aqi_range_labels, range_value: aqi['data']['iaqi']['pm25']['v'].to_s)
    # banner_str = "\x03#{colors[:grey]}#{banner_str}\x03"
  elsif config.mode == :slack
    reply += color_str_with_value(range_str: aqi_range_labels, range_value: aqi['data']['iaqi']['pm25']['v'].to_s)
  end

  if aqi['data']['iaqi']['pm25']
    reply += 'pm25: ' + color_str(aqi['data']['iaqi']['pm25']['v'].to_s) + '  '
    ugm3 = pm25_to_ugm3 aqi['data']['iaqi']['pm25']['v'].to_s
    reply += "µg/m³(est): #{ugm3}  "
  end
  if aqi['data']['iaqi']['pm10']
    reply += 'pm10: ' + color_str(aqi['data']['iaqi']['pm10']['v'].to_s) + '  '
  end

  updated_at = Time.parse aqi['data']['time']['s']
  diff = (Time.now - updated_at).to_i / 60

  reply += "updated #{color_str(diff.to_s)} minutes ago.  #{banner_str}"

  response.reply reply
end
get_aqi_deets(response) click to toggle source
# File lib/lita/handlers/onewheel_aqi.rb, line 192
def get_aqi_deets(response)
  loc = get_location(response)
  aqi = get_observed_aqi(loc)

  if aqi['status'] == 'nug'
    response.reply "Status is 'nug' for aqi station near #{loc['name']}"
    return
  end

  reply = "AQI for #{loc[:name]}, "

  banner_str = "(#{aqi['data']['city']['url']})"

  if config.mode == :irc
    reply += color_str_with_value(range_str: aqi_range_labels, range_value: aqi['data']['iaqi']['pm25']['v'].to_s)
    banner_str = "\x03#{colors[:grey]}#{banner_str}\x03"
  end

  if aqi['data']['iaqi']['co']
    reply += 'co²: ' + aqi['data']['iaqi']['co']['v'].to_s + '  '
  end
  if aqi['data']['iaqi']['h']
    reply += 'humidity: ' + aqi['data']['iaqi']['h']['v'].to_s + '%  '
  end
  # if aqi['data']['iaqi']['p']
  #   reply += 'pressure: ' + aqi['data']['iaqi']['p']['v'].to_s + 'mb  '
  # end
  if aqi['data']['iaqi']['pm25']
    reply += 'pm25: ' + color_str(aqi['data']['iaqi']['pm25']['v'].to_s) + '  '
    ugm3 = pm25_to_ugm3 aqi['data']['iaqi']['pm25']['v']
    reply += "µg/m³(est): #{ugm3}  "
  end
  if aqi['data']['iaqi']['pm10']
    reply += 'pm10: ' + color_str(aqi['data']['iaqi']['pm10']['v'].to_s) + '  '
  end
  if aqi['data']['iaqi']['t']
    reply += 'temp: ' + aqi['data']['iaqi']['t']['v'].to_s + 'C  '
  end

  updated_at = Time.parse aqi['data']['time']['s']
  diff = (Time.now - updated_at).to_i / 60

  reply += "updated #{color_str(diff.to_s)} minutes ago.  #{banner_str}"
  response.reply reply
end
get_location(response, persist = true) click to toggle source

Perform a geocoder lookup based on a) the query or b) the user's serialized state. If neither of those exist, default to config location.

# File lib/lita/handlers/onewheel_aqi.rb, line 94
def get_location(response, persist = true)
  user = response.user
  query = nil
  if response.matches[0].is_a?(Array) and !response.matches[0].empty?
    query = response.matches[0][0]
  end

  Lita.logger.debug "Performing geolookup for '#{user.name}' for '#{query}'"

  if query.nil? or query.empty?
    Lita.logger.debug "No query specified, pulling from redis #{REDIS_KEY}, #{user.name}"
    serialized_geocoded = redis.hget(REDIS_KEY, user.name)
    unless serialized_geocoded == 'null' or serialized_geocoded.nil?
      geocoded = JSON.parse(serialized_geocoded)
    end
    Lita.logger.debug "Cached location: #{geocoded.inspect}"
  end

  query = (query.nil?)? 'Portland, OR' : query
  Lita.logger.debug "q & g #{query.inspect} #{geocoded.inspect}"

  unless geocoded
    uri = "https://atlas.p3k.io/api/geocode?input=#{URI.escape query}"
    Lita.logger.debug "Redis hget failed, performing lookup for #{query} on #{uri}"
    # geocoded = optimistic_geo_wrapper query, config.geocoder_key
    geocoded = JSON.parse RestClient.get(uri)
    Lita.logger.debug "Geolocation found.  '#{geocoded.inspect}' failed, performing lookup"
    if persist
      redis.hset(REDIS_KEY, user, geocoded.to_json)
    end
  end

  Lita.logger.debug "geocoded: '#{geocoded}'"
  loc = {
    name: geocoded['best_name'],
    lat: geocoded['latitude'],
    lng: geocoded['longitude']
  }

  Lita.logger.debug "loc: '#{loc}'"

  loc
end
get_observed_aqi(loc) click to toggle source
# File lib/lita/handlers/onewheel_aqi.rb, line 138
def get_observed_aqi(loc)
  uri = "http://api.waqi.info/feed/geo:#{loc[:lat]};#{loc[:lng]}/?token=#{config.api_key}"
  Lita.logger.debug "Getting aqi from #{uri}"

  observed_response = RestClient.get(uri)
  observed_aqi = JSON.parse(observed_response)
  Lita.logger.debug 'Observed response: ' + observed_aqi.inspect
  observed_aqi
end
optimistic_geo_wrapper(query) click to toggle source

Geographical stuffs Now with less caching!

# File lib/lita/handlers/onewheel_aqi.rb, line 269
def optimistic_geo_wrapper(query)
  geocoded = nil
  result = ::Geocoder.search(query)
  puts result.inspect
  geocoded = result[0].data if result[0]
  geocoded
end
pm25_to_ugm3(pm25) click to toggle source

Particulate Matter 2.5 to micrograms per cubic meter

# File lib/lita/handlers/onewheel_aqi.rb, line 278
def pm25_to_ugm3(pm25)
  ranges = {
    0..50 => [0, 50, 0.0, 12.0],
    51..100 => [51, 100, 12.1, 35.4],
    101..150 => [101, 150, 35.5, 55.4],
    151..200 => [151, 200, 55.5, 150.4],
    201..300 => [201, 300, 150.5, 250.4],
    301..999 => [301, 999, 250.5, 999]
  }
  ranges.keys.each do |range_key|
    next unless range_key.cover? pm25.to_i
    low = ranges[range_key][0]
    high = ranges[range_key][1]
    min = ranges[range_key][2]
    max = ranges[range_key][3]
    step = (max - min) / (high - low)
    ugm3 = (pm25.to_i - low) * step + min
    return ugm3.round(2)
  end
end