Giter Site home page Giter Site logo

metar-parser's Introduction

Build Status

metar-parser

Get latest weather reports from weather stations worldwide

The information comes from the National Oceanic and Atmospheric Association's raw data source.

Installation

require 'metar'

Examples

Hello World

This prints the latest weather report for Portland International Airport:

station = Metar::Station.find_by_cccc('KPDX')
puts station.report.to_s

Using Your Own Raw Data

The parser needs to know the full date when the reading was taken. Unfortunately, the METAR string itself only contains the day of the month.

When you know the date of the reading

Use Metar::Raw::Data and supply the date as the second parameter:

metar_string = "KHWD 280554Z AUTO 29007KT 10SM OVC008 14/12 A3002 RMK AO2 SLP176 T01390117 10211\n"
raw    = Metar::Raw::Data.new(metar_string, reading_date)
parser = Metar::Parser.new(raw)

When you do not know the date

Use Metar::Raw::Metar - the library will choose the date as the most recent day with the day of the month indicated in the METAR string:

I.e. on 11th April 2016:

metar_string = "KHWD 280554Z AUTO 29007KT 10SM OVC008 14/12 A3002 RMK AO2 SLP176 T01390117 10211\n"
raw    = Metar::Raw::Metar.new(metar_string)
raw.time.to_s                              # => "2016-03-28"
parser = Metar::Parser.new(raw)

Access Specific Data

station = Metar::Station.find_by_cccc('KPDX')
parser  = station.parser
puts parser.temperature.value

Countries

List countries:

puts Metar::Station.countries

Find a country's weather stations:

spanish = Metar::Station.find_all_by_country('Spain')

Translations

Translations are available for the following languages (and region):

  • :de
  • :en
  • :'en-US'
  • :it
  • :'pt-BR'

Thanks to the I18n gem's fallback mechanism, under regional locales, language generic translations will be used if a region-specific translation is not available. I.e.

I18n.locale = :'en-US'
I18n.t('metar.station_code.title') # station code

The METAR Format

See doc/metar_format.

Compliance

By default, the parser runs in 'loose' compliance mode. That means that it tries to accept non-standard input.

If you only want to accept standards-compliant METAR strings, do this:

Metar::Parse.compliance = :strict

Contributors

metar-parser's People

Contributors

cmiconi avatar douglasr avatar drmwndr avatar epicdraws avatar joeyates avatar math avatar olleolleolle avatar parabuzzle avatar tkrajcar avatar weatherpixie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

metar-parser's Issues

Invalid visibility from report (4,000km?)

VABB 282210Z 22005KT 4000 HZ SCT018 FEW025TCU BKN100 28/25 Q1003 NOSIG

The following METAR leads to a 4,000KM visibility reading. I am not familiar with the non-US format to figure out what is going on. My guess is that means 4,000 meters? Seems to work fine for other international, but that is Mumbai Airport in India.

Thanks again for all the help--this gem is looking pretty stable overall and is exactly what I needed.

Support for multiple station retrieval in one request

First of all, wanted to say this gem looks amazing. I wrote my own but it is much more fragile. One downside I see is the usage of FTP, and the associated limitation of retrieving METARs for only one station at a time. Would it be possible to offer an HTTP based approach that returns an array of METAR objects? Thanks again for the great work!

Unneccesary station lookup required when passing raw METAR data

When using the approach of passing in raw METAR data to a Metar::Raw object, the @station variable (a) requires an unneccesary lookup and (b) can often be null, even with valid data. The parsing should be able to complete with a nil Station object. The fix I applied is for all methods requiring @station lookups is simply to return the string "Unknown".

Metar::ParseError: Expecting temperature/dew point on valid METAR

Metar::ParseError: Expecting temperature/dew point, found '36007KT' for KHWD 280554Z AUTO 36007KT 10SM OVC008 14/12 A3002 RMK AO2 SLP176 T01390117 10211

I extended the ParseError string to show the raw METAR passed in, and see a number of failures with this same look. The METAR is well formed, so I am not sure what the issue is. Most of the time, things are working fine.

I used approach 1 that I discussed in #6, where I get the METAR raw reports myself, then manually create a Metar::Raw and parser, and use that data.

Does the METAR above look off to you at all?

Parsing Remarks

While currently remarks get parsed into a flat text field, it may be nice to try to gather key data from them. For example, known turbulence, maintenance, and other high priority data is very interesting, and unfortunate to essentially ignore.

Parser gives up if invalid winds present

Given the following real METAR that's current:
KSEE 181947Z 000000KT 10SM SKC 22/10 A2999

The parser appears to give up on parsing or returning anything after the winds; sea_level_pressure, temperature, etc are all blank.

Unfortunately, I have learned that it's annoyingly common for real-world METARs to have incorrectly-formatted winds; it would be nice if the parser would not bail out in these cases.

Unexpected parse error with raw METAR

I don't have permission to reopen #15, but its not fixed, given this METAR:

EKRK 301620Z AUTO 20008KT 9999NDV FEW038/// SCT055/// BKN090/// 17/11 Q1012

Metar::ParseError (Expecting temperature/dew point, found 'FEW038///' in EKRK 301620Z AUTO 20008KT 9999NDV FEW038/// SCT055/// BKN090/// 17/11 Q1012):

Unexpected parse error with raw METAR

Metar::ParseError: Expecting temperature/dew point, found 'BKN///' in RJBE 292200Z 24003KT 9999 FEW012 BKN/// 28/23 Q1009

Not familiar enough with non-US format to understand the issue. Thanks again. I have been testing 35+ airports every few minutes, and getting down to very, very few issues. Great work!

NoMethodError when parsing density altitude

NoMethodError is being raised when parsing a METAR with a density altitude, such as:

METAR CYBW 010000Z AUTO VRB04KT 9SM SCT070 13/M01 A3028 RMK SLP282 DENSITY ALT 4100FT=

NoMethodError: undefined method `[]' for nil:NilClass
    from .rvm/gems/ruby-2.2.1/bundler/gems/metar-parser-b3786bf13c39/lib/metar/data.rb:627:in `parse'

If you remove the density altitude from the METAR then it is parsed as per normal.

Unable to parse variable gusting winds

METAR:
LGRP 221250Z VRB09G23KT 9999 FEW010 BKN020 OVC080 16/13 Q1003 WS R07 WS R25 RMK R25 10013G24KT

Results in a nil object for winds, leading to our app displaying a very misleading 0.

Parse Error with CCA after time

Not sure what CCA means, but several stations report it:

  • CYZU: Expecting temperature/dew point, found 'CCA' in CYZU 310100Z CCA 26004KT 15SM FEW009 BKN040TCU BKN100 OVC210 15/12 A2996 RETS
    RMK SF1TCU4AC2CI1 SLP149
  • CWWU: Expecting temperature/dew point, found 'CCA' in CWWU 302300Z CCA 09007KT 8SM -DZ OVC007 16/14 A3003 RMK SF8 LAST OBS/NEXT
    310800Z SLP170
  • CYFS: Expecting temperature/dew point, found 'CCA' in CYFS 310100Z CCA 32003KT 15SM SCT035CB BKN080 22/17 A2969 RETS RMK CB3AC2 SLP058
  • CYBK: Expecting temperature/dew point, found 'CCA' in CYBK 310100Z CCA 36012KT 20SM FEW015 13/03 A2984 RMK SC2 SLP105

Unexpected error parsing causes complete hang

This is a critical issue which causes a complete system hang upon encountering.

Error Parsing MPBO 022100Z 00000KT 9000 -RA FEW016 BKN080 26/23 Q1014 REY WET:

Not even sure what is going wrong here.

Parse Error reading RVR

Got this error with a potentially non-standard RVR?

  • CYYT: Expecting temperature/dew point, found 'R11/2600FT/N' in CYYT 310100Z 13013KT 3/8SM R11/2600FT/N R16/1800FT/N -RA FG VV001 14/14 A3002
    RMK FG8 SLP167

Consider: Serialization for Metar::Parser

In some basic performance tests, I have found the average airport takes 50-250ms to parse, with the average in the 150ms range. Given my use case, it is common major airports will be hit often, and this parsing is redundant. Ideally, I would cache the Metar::Parser object and expire it when a new METAR report is available. However, Metar::Parser does not support serialization. Without this, there is no way to cache the expensive parsing results for reuse.

Unexpected Error parsing METAR

TypeError: nil is not a symbol
from /Users/derek/.bundler/ruby/1.8/metar-parser-81292b1535fc/lib/metar/data.rb:274:in send' from /Users/derek/.bundler/ruby/1.8/metar-parser-81292b1535fc/lib/metar/data.rb:274:inparse'
from /Users/derek/.bundler/ruby/1.8/metar-parser-81292b1535fc/lib/metar/parser.rb:236:in collect_runway_visible_range' from /Users/derek/.bundler/ruby/1.8/metar-parser-81292b1535fc/lib/metar/parser.rb:245:inseek_runway_visible_range'

for raw METAR:

  • LFJR 310130Z AUTO 00000KT 0300 R26/0750V1200U FG VV/// 12/11 Q1019

Idea: access to original chunks

I have a situation where I want to parse the METAR, storing various data in a database for querying but then also rendering the original chunks, as posted in the METAR. As an example, if the wind chunk was "36007KT", that is nicely parsed and stored as 0 degrees and 3.60111 m/s which I store in the database. However, I would like to be able to then render the original text to the user. Although I could reconstruct the output by converting units and handling any special cases (such as 0 deg being displayed as 360 deg) I'm thinking it might make more sense to simply have an internal hash which maintains the original text as parsed. @joeyates, is this something that you would accept a pull request for?

Visibility shows wrong unit when SM are parsed

Repro:

Taking the example metar:

metar_string = "KHWD 280554Z AUTO 29007KT 10SM OVC008 14/12 A3002 RMK AO2 SLP176 T01390117 10211\n"
raw    = Metar::Raw::Metar.new(metar_string)
parser = Metar::Parser.new(raw)
parser.visibility.distance
 => #<Metar::Data::Distance:0x007fdab0977df8 @units=:miles, @value=16093.44> 

This is wrong/unexpected. It either needs to be

 => #<Metar::Data::Distance:0x007fdab0977df8 @units=:miles, @value=10000.00> 

or

 => #<Metar::Data::Distance:0x007fdab0977df8 @units=:meters, @value=16093.44> 

The bug seems to be in
https://github.com/joeyates/metar-parser/blob/master/lib/metar/data/visibility.rb#L20
https://github.com/joeyates/metar-parser/blob/master/lib/metar/data/visibility.rb#L27
https://github.com/joeyates/metar-parser/blob/master/lib/metar/data/visibility.rb#L33

When I try

Metar::Data::Distance.miles(10)
 => #<Metar::Data::Distance:0x007fdab08e6088 @units=:meters, @value=16093.44>

it is correct. It seems as if the units=:miles is unnecessary. This is not caught by the specs.

Problem parsing METAR date/time at month rollover

There is a date wrapping problem when a METAR issued just before midnight UTC of a month rollover is parsed shortly after month rollover. For example, the following METAR was issued at 2359 UTC on March 31st:

METAR OPPS 312359Z 23006KT 4000 HZ SCT040 SCT100 17/12 Q1011

but then parsed at 00:02:11 UTC on 01 Apr (about three minutes after it was issued). The call to Parser.time() returns May 01 23:59 UTC, which is a result of trying to construct April 31st when the call is made to Time.gm() which then corrects the date to the equivalent of April 31, which is May 1.

@joeyates : I'm going to add some logic to handle this month end (and probably year end also) but I wondered if you had any thoughts about this in terms of how you would like it handled? That way you can simply use my pull request (when I submit it).

Cheers,
Douglas

Parse Error with -VCTSRA

2 METARs which contain -VCTSRA seem to cause errors:

  • KMNH: Expecting temperature/dew point, found '-VCTSRA' in KMNH 310131Z AUTO 03008KT 10SM -VCTSRA SCT046 SCT065 OVC090 16/14 A3031 RMK AO2
    LTG DSNT ALQS P0001
  • K2V5: Expecting temperature/dew point, found '-VCTSRA' in K2V5 310135Z AUTO 36005KT 10SM -VCTSRA BKN065 BKN075 OVC100 29/18 A3008 RMK AO2
    LTG DSNT ALQS T02920182

Sort out Rakefile

Currently, under 1.8.7, the warnings are:
rake/gempackagetask is deprecated. Use rubygems/package_task instead
WARNING: 'require 'rake/rdoctask'' is deprecated. Please use 'require 'rdoc/task' (in RDoc 2.4.2+)' instead.
at .../rake-0.9.2.2/lib/rake/rdoctask.rb

Parse date from raw METARs

When passing raw METARs to Raw, you currently manually add the date. This can be parsed from the METAR and should not become the burden of consumers.

NoSuchMethod error for parser.raw_attributes

There are quite a few METARs that throw a NoSuchMethod error for raw against a String when calling parser.raw_attributes.

I captured some here for you to evaluate:

Error: undefined method `raw' for "HZ":String (raw: KSJC 272353Z 30011KT 10SM FEW030 SCT050 SCT100 34/09 A2980 RMK AO2 SLP091 HZ FEW030 HZ SCT050 T03390094 10339 20283 56019 $)
Error: undefined method `raw' for "$":String (raw: KPQL 272353Z AUTO 00000KT 10SM CLR 26/22 A2983 RMK AO2 SLP103 T02560222 10328 20256 58007 $)
Error: undefined method `raw' for "$":String (raw: KPSP 272353Z 10008KT 10SM CLR 39/08 A2977 RMK AO2 SLP077 T03940083 10400 20322 56016 $)
Error: undefined method `raw' for "$":String (raw: KPTK 272353Z 30004KT 10SM SCT040 BKN100 BKN250 20/16 A2976 RMK AO2 SLP072 T02000161 10233 20200 50006 $)
Error: undefined method `raw' for "PK":String (raw: KPUC 272353Z AUTO 32019G25KT 10SM CLR 19/M04 A3022 RMK AO2 PK WND 32026/2342 SLP186 T01891044 10211 20183 53002)
Error: undefined method `raw' for "PK":String (raw: KPWA 272353Z 02025G35KT 10SM BKN022 OVC030 17/11 A2987 RMK AO2 PK WND 03043/2300 SLP106 T01670106 10283 20167 53054 $)
Error: undefined method `raw' for "$":String (raw: KPQL 272353Z AUTO 00000KT 10SM CLR 26/22 A2983 RMK AO2 SLP103 T02560222 10328 20256 58007 $)
Error: undefined method `raw' for "$":String (raw: KPSP 272353Z 10008KT 10SM CLR 39/08 A2977 RMK AO2 SLP077 T03940083 10400 20322 56016 $)
Error: undefined method `raw' for "$":String (raw: KPTK 272353Z 30004KT 10SM SCT040 BKN100 BKN250 20/16 A2976 RMK AO2 SLP072 T02000161 10233 20200 50006 $)
Error: undefined method `raw' for "PK":String (raw: KRDD 272353Z 01020G27KT 10SM FU CLR 36/00 A2991 RMK AO2 PK WND 01034/2335 SLP123 T03610000 10367 20283 56018)
Error: undefined method `raw' for "PK":String (raw: KPUC 272353Z AUTO 32019G25KT 10SM CLR 19/M04 A3022 RMK AO2 PK WND 32026/2342 SLP186 T01891044 10211 20183 53002)
Error: undefined method `raw' for "PK":String (raw: KPWA 272353Z 02025G35KT 10SM BKN022 OVC030 17/11 A2987 RMK AO2 PK WND 03043/2300 SLP106 T01670106 10283 20167 53054 $)
Error: undefined method `raw' for "$":String (raw: KRKP 272353Z AUTO 15008KT 8SM CLR A2971 RMK AO2 SLP064 56007 $)
Error: undefined method `raw' for "PK":String (raw: KRDD 272353Z 01020G27KT 10SM FU CLR 36/00 A2991 RMK AO2 PK WND 01034/2335 SLP123 T03610000 10367 20283 56018)
Error: undefined method `raw' for "$":String (raw: KRKP 272353Z AUTO 15008KT 8SM CLR A2971 RMK AO2 SLP064 56007 $)
Error: undefined method `raw' for "$":String (raw: KRSW 272353Z 00000KT 10SM FEW120 26/23 A2989 RMK AO2 SLP119 60026 T02560228 10344 20250 55000 $)
Error: undefined method `raw' for "PK":String (raw: KRVS 272353Z 36017G31KT 10SM -RA BKN017 BKN022 OVC027 16/13 A2985 RMK AO2 PK WND 01040/2316 SLP113 P0001 60001 T01610128 10267 20161 53041)
Error: undefined method `raw' for "RAE04B26E37":String (raw: KSTC 272353Z 29007KT 10SM OVC080 12/11 A2976 RMK AO2 LTG DSNT E RAE04B26E37 SLP090 P0001 60002 T01220106 10167 20122 53016)

Parse Error with some fractional visibility

While you accounted for some of the fractional visibilities, it seems there can be even more arbitrary ones given:

KMWN: Expecting temperature/dew point, found '3/16SM' in KMWN 310048Z 25017KT 3/16SM FG SCT000 BKN200 12/12 RMK FG SCT000 FG INTMT

Unknown error parsing METAR

Received the following error, and unsure of the cause:
Metar::ParseError: Expecting temperature/dew point, found '6000SW' for EGLL 291520Z 23010KT 9999 6000SW VCSH SCT020CB 16/10 Q1011 TEMPO TSRA

note: I added the raw METAR to the error strings and it's quite useful in a production system. I would recommend this gets added to the gem errors for easier debugging.

Parse Recent Weather

CYQH: Expecting temperature/dew point, found 'RETS' in CYQH 310110Z 00000KT 20SM SCT035CB BKN050 RETS RMK CB4SC1

Here RETS is the 'Recent weather phenomena' group (WMO 15.13.1)

m9t warnings

Hi,

I've just been using one of your examples and received this output:-

/usr/lib/ruby/gems/1.8/gems/m9t-0.2.3/lib/m9t/distance.rb:10: warning: already initialized constant DEFAULT_OPTIONS
/usr/lib/ruby/gems/1.8/gems/m9t-0.2.3/lib/m9t/distance.rb:15: warning: already initialized constant CONVERSIONS
name: Luton Airport
country: United Kingdom
time: 17:50
wind: 4km/h variable direction
visibility: more than 10km
sky: few clouds
temperature: 10°C

I can't seem to get rid of it, even after updating m9t to the latest rev (0.3.1). I am running Ruby version 1.8.7 on Debian 6.05.

offer to help maintain

Hi @joeyates,

I'm working on some production software using this gem, and wanted to offer to help support you since I'll be depending on this gem for the near future and I figured you might be interested in a hand after going it solo for 7 years :)

No pressure - if you're not interested, feel free to close.

Attempt to parse invalid date/times

Sometimes we encounter datetimes that while invalid, still may be parseable.

Error Parsing CWND M01/M01 RMK 3004 T10081008: Expecting datetime, found 'M01/M01' in CWND M01/M01 RMK 3004 T10081008
Error Parsing MMCE 21645Z 12010KT 8SM SKC 29/26 A2992 RMK: Expecting datetime, found '21645Z' in MMCE 21645Z 12010KT 8SM SKC 29/26 A2992 RMK
Error Parsing HKML 1600Z 19010KT 9999 FEW022 25/22 Q1015: Expecting datetime, found '1600Z' in HKML 1600Z 19010KT 9999 FEW022 25/22 Q1015

Parser generates error on initialize

When following your example I get the following error after declaring parser = Metar::Parser.new(raw)

ArgumentError: wrong number of arguments (1 for 0)
from /Users/morten/.rvm/gems/ruby-1.9.2-head/gems/m9t-0.2.2/lib/m9t/base.rb:129:in block (2 levels) in define_conversion' from /Users/morten/.rvm/gems/ruby-1.9.2-head/gems/m9t-0.2.2/lib/m9t/base.rb:99:inmethod_missing'
from /Users/morten/.rvm/gems/ruby-1.9.2-head/gems/m9t-0.2.2/lib/m9t/base.rb:109:in to_s' from /Users/morten/.rvm/gems/ruby-1.9.2-head/gems/metar-parser-0.9.8/lib/metar/data.rb:143:into_s'
from /Users/morten/.rvm/gems/ruby-1.9.2-head/gems/railties-3.1.0/lib/rails/commands/console.rb:45:in start' from /Users/morten/.rvm/gems/ruby-1.9.2-head/gems/railties-3.1.0/lib/rails/commands/console.rb:8:instart'
from /Users/morten/.rvm/gems/ruby-1.9.2-head/gems/railties-3.1.0/lib/rails/commands.rb:40:in <top (required)>' from script/rails:6:inrequire'
from script/rails:6:in `

'

Parse Error when missing temperature/dew point

While I am unclear if temp/dew point is a strict requirement for METARs, when I ran a test of every single airport worldwide, a number of them came back without it. Here are a few examples:

  • PADE: Expecting temperature/dew point, found 'A2981' in PADE 310053Z AUTO 27013KT 10SM BKN027 OVC032 A2981 RMK SLP096 TSNO $ VIA AUTODIAL
  • KJFX: Expecting temperature/dew point, found 'A2993' in KJFX 310135Z AUTO 00000KT 10SM CLR A2993 RMK A02 P-128
  • KEDU: Expecting temperature/dew point, found 'RMK' in KEDU 310135Z AUTO 10SM RMK AO1
  • KPOC: Expecting temperature/dew point, found 'A2994' in KPOC 302147Z 24012KT 10SM SCT100 A2994

I ran the test separately with US and non-US. The above are only from US.

Parse Error with RADZ weather flag

UPDATE: RETS appears not valid, so switching this to reflect the (valid) -RADZ issue.

Seems to be an error parsing RETS which I believe is valid.

CYQH: Expecting temperature/dew point, found 'RETS' in CYQH 310110Z 00000KT 20SM SCT035CB BKN050 RETS RMK CB4SC1

Parser fails on last chunk when end of METAR character (=) encountered

If an end of METAR character (=) immediately follows the last chunk (and there is no remarks section) then the last chunk fails to be parsed. For example, in both the following cases, the last chunk is left as "unparsed":

METAR LPPT 070530Z 34003KT 310V010 CAVOK 14/12 Q1013=
METAR YMML 080800Z 17007KT CAVOK 13/05 Q1020 NOSIG=

However, if there is a space between the last chunk and the = character or there is a remarks section then only the = character is listed as unparsed. For example:

METAR LPPT 070500Z 33004KT CAVOK 14/12 Q1013 =
METAR CYBW 070500Z AUTO 14007KT 9SM OVC027 01/M07 A3018 RMK SLP265=

In both these cases, the complete core data in the METAR is parsed, though in the second example the sea level pressure of the remarks, which should be parsed, is not parsed -- again due to the = character.

It seems that the best course of action here is to drop the = character if it's at the end of the METAR since it is part of the specification. If you advise on how you'd like to proceed I can code up a pull request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.