Skip to content

Instantly share code, notes, and snippets.

@christianmeichtry
Last active December 17, 2015 16:59
Show Gist options
  • Save christianmeichtry/5642294 to your computer and use it in GitHub Desktop.
Save christianmeichtry/5642294 to your computer and use it in GitHub Desktop.
# Encoding: utf-8
# IN GEMFILE : gem 'wombat' #does the scraping magic
class WeatherData < ActiveRecord::Base
require 'open-uri'
require 'digest/md5'
attr_accessible :max_wind, :mean_wind, :sea_level_pressure, :station_code, :station_id, :temp, :time_stamp, :wind_direction, :conditions
belongs_to :station
def self.new_from_metar(station_code)
begin
metar_station = Metar::Station.find_by_cccc(station_code)
parser = metar_station.parser
station = Station.find_or_create_by_title(:title => metar_station.name, :latitude => metar_station.latitude, :longitude => metar_station.longitude, :code => parser.station_code)
data = station.weather_datas.where(:time_stamp => parser.time).first_or_create :sea_level_pressure => parser.sea_level_pressure.to_f * 1000,
:station_id => station.id,
:conditions => parser.present_weather,
:mean_wind => parser.wind.to_s.split('k')[0].to_i,
:wind_direction => WeatherData.convert_to_degrees(parser.wind)
rescue Exception => msg
logger.error msg
end
end
def self.north_south_pressure_difference(limit = 1)
lszh = Station.where(:code => "LSZH").first
lsza = Station.where(:code => "LSZA").first
lszh.weather_datas.order("time_stamp DESC").limit(limit).map { |zrh| {:pressure_gradient => (lsza.weather_datas.where(:time_stamp => zrh.time_stamp).first ? lsza.weather_datas.where(:time_stamp => zrh.time_stamp).first.sea_level_pressure - zrh.sea_level_pressure : nil), :time => zrh.time_stamp} }
end
def self.refresh_data
WeatherData.new_from_metar("LSZA")
WeatherData.new_from_metar("LSZH")
WeatherData.import_new_from_balise_db
WeatherData.new_from_scraper
end
def self.new_from_chalais
results = open "http://chalais.atelier-agile.ch/winds/current.json"
chalais = JSON.parse(results.read)
station = Station.find_or_create_by_title(:title => 'Chalais')
data = station.weather_datas.where(:time_stamp => chalais[3]).first_or_create :mean_wind => chalais[0],
:max_wind => chalais[1],
:wind_direction => chalais[2]
end
def self.conditions_for(title, limit = 1)
station = Station.where(:title => title).first
station.weather_datas.order("time_stamp DESC").limit(limit)
end
def self.import_new_from_balise_db
station = Station.find_or_create_by_title(:title => 'Chalais')
# BaliseData.where(["time > ?", (Time.now - 1.month)]).find_each do |data|
BaliseData.where(["time > ?", WeatherData.order("time_stamp DESC").limit(1).first.time_stamp]).find_each do |data|
case data.sensor_id
when 2
new_measure = station.weather_datas.where(:time_stamp => data.time).first_or_create
new_measure.update_attribute(:mean_wind, data.value)
when 3
new_measure = station.weather_datas.where(:time_stamp => data.time).first_or_create
new_measure.update_attribute(:max_wind, data.value)
when 1
new_measure = station.weather_datas.where(:time_stamp => data.time).first_or_create
new_measure.update_attribute(:wind_direction, data.value)
when 4
new_measure = station.weather_datas.where(:time_stamp => data.time).first_or_create
new_measure.update_attribute(:temp, data.value)
end
end
end
def self.new_from_scraper
sample = scraped_weather_data
set_data_for("Sion", "sion", sample)
set_data_for("Visp", "visp", sample)
set_data_for("Montana", "montana", sample)
set_data_for("Gütsch", "guetsch", sample)
end
# def self.wind_for_visp
# url = "http://api.wetter.com/forecast/weather"
# search = "CH0CH4146"
# cs = Digest::MD5.hexdigest("#{PROJEKT}#{WETTER_API_KEY}#{search}")
#
# results = open "#{url}/city/#{search}/project/#{PROJEKT}/cs/#{cs}/output/json"
# results.read
# end
def cardinal_points
case wind_direction.to_i
when 0..(45-22)
"Nord"
when (45-22)..(90-22)
"Nord-Est"
when (90-22)..(135-22)
"Est"
when (135-22)..(180-22)
"Sud-Est"
when (180-22)..(225-22)
"Sud"
when (225-22)..(270-22)
"Sud-Ouest"
when (270-22)..(315-22)
"Ouest"
when (315-22)..(360-22)
"Nord-Ouest"
when (360-22)..360
"Nord"
else "Variable"
end
end
def self.convert_to_degrees(metar_wind)
direction_string = metar_wind.to_s.split(" ").last
case direction_string
when "N"
0
when "E"
90
when "S"
180
when "W"
270
when "WSW"
247.50
when "NNE"
22.50
else
-1
end
end
def self.scraped_weather_data
Wombat.crawl do
base_url "http://www.meteoschweiz.admin.ch"
path "/web/de/wetter/aktuelles_wetter.par0010.html?allStations=1"
measure_date css: "p.text"
visp css: "#karte_data_aktueller_wind_numerisch___VIS"
sion css: "#karte_data_aktueller_wind_numerisch___SIO"
montana css: "#karte_data_aktueller_wind_numerisch___MVE"
guetsch css: "#karte_data_aktueller_wind_numerisch___GUE"
end
end
def self.set_data_for(title, key, sample)
date = sample["measure_date"]
day = date.split(" ")[2]
time = date.split(" ")[3]
time_stamp = Time.parse("#{day} #{time.gsub(".", ":")}")
station = Station.find_or_create_by_title(:title => title)
new_measure = station.weather_datas.where(:time_stamp => time_stamp).first_or_create
new_measure.update_attributes :max_wind => sample[key].split("|")[2].to_i,
:mean_wind => sample[key].split("|")[1].to_i,
:wind_direction => sample[key].split("|")[0].to_i
end
def time_stamp_corrected
if self.station_id == 5
time_stamp - 2.hours
else
time_stamp
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment