def test_040_parseModifier_default(self): """Check default 'modifier' value.""" self.assertEqual( Metar.Metar("KEWR").mod, "AUTO" )
def raisesParserError(code): """Helper to test the a given code raises a Metar.ParserError.""" with pytest.raises(Metar.ParserError): Metar.Metar(code)
def test_041_parseModifier(): """Check parsing of 'modifier' groups.""" assert Metar.Metar(sta_time + "AUTO").mod == "AUTO" assert Metar.Metar(sta_time + "COR").mod == "COR"
def test_issue84_trimequals(trailstr): """A trailing = in METAR should not trip up the ingest.""" code = ("KABI 031752Z 30010KT 6SM BR FEW009 OVC036 02/01 A3003 RMK AO2 " "SLP176 60001 I%i003 T00170006 10017 21006 56017") assert Metar.Metar("%s%s" % (code, trailstr)).decode_completed
def process(ncfn): """Process this file """ pgconn = get_dbconn("iem") icursor = pgconn.cursor() xref = {} icursor.execute(""" SELECT id, network from stations where network ~* 'ASOS' or network = 'AWOS' and country = 'US' """) for row in icursor: xref[row[0]] = row[1] icursor.close() nc = ncopen(ncfn) data = {} for vname in [ "stationId", "observationTime", "temperature", "dewpoint", "altimeter", # Pa "windDir", "windSpeed", # mps "windGust", # mps "visibility", # m "precipAccum", "presWx", "skyCvr", "skyCovLayerBase", "autoRemark", "operatorRemark", ]: data[vname] = nc.variables[vname][:] for qc in ["QCR", "QCD"]: vname2 = vname + qc if vname2 in nc.variables: data[vname2] = nc.variables[vname2][:] for vname in ["temperature", "dewpoint"]: data[vname + "C"] = temperature(data[vname], "K").value("C") data[vname] = temperature(data[vname], "K").value("F") for vname in ["windSpeed", "windGust"]: data[vname] = (masked_array(data[vname], units("meter / second")).to( units("knots")).magnitude) data["altimeter"] = pressure(data["altimeter"], "PA").value("IN") data["skyCovLayerBase"] = distance(data["skyCovLayerBase"], "M").value("FT") data["visibility"] = distance(data["visibility"], "M").value("MI") data["precipAccum"] = distance(data["precipAccum"], "MM").value("IN") stations = chartostring(data["stationId"][:]) presentwxs = chartostring(data["presWx"][:]) skycs = chartostring(data["skyCvr"][:]) autoremarks = chartostring(data["autoRemark"][:]) opremarks = chartostring(data["operatorRemark"][:]) def decision(i, fieldname, tolerance): """Our decision if we are going to take a HFMETAR value or not""" if data[fieldname][i] is np.ma.masked: return None if data["%sQCR" % (fieldname, )][i] == 0: return data[fieldname][i] # Now we have work to do departure = np.ma.max(np.ma.abs(data["%sQCD" % (fieldname, )][i, :])) # print("departure: %s tolerance: %s" % (departure, tolerance)) if departure <= tolerance: return data[fieldname][i] return None for i, sid in tqdm( enumerate(stations), total=len(stations), disable=(not sys.stdout.isatty()), ): sid3 = sid[1:] if sid[0] == "K" else sid ts = datetime.datetime(1970, 1, 1) + datetime.timedelta( seconds=data["observationTime"][i]) ts = ts.replace(tzinfo=pytz.UTC) mtr = "%s %sZ AUTO " % (sid, ts.strftime("%d%H%M")) network = xref.get(sid3, "ASOS") iem = Observation(sid3, network, ts) # 06019G23KT val = decision(i, "windDir", 15) if val is not None: iem.data["drct"] = int(val) mtr += "%03i" % (iem.data["drct"], ) else: mtr += "///" val = decision(i, "windSpeed", 10) if val is not None: iem.data["sknt"] = int(val) mtr += "%02i" % (iem.data["sknt"], ) else: mtr += "//" val = decision(i, "windGust", 10) if val is not None and val > 0: iem.data["gust"] = int(val) mtr += "G%02i" % (iem.data["gust"], ) mtr += "KT " val = decision(i, "visibility", 4) if val is not None: iem.data["vsby"] = float(val) mtr += "%sSM " % (vsbyfmt(iem.data["vsby"]), ) presentwx = presentwxs[i] if presentwx != "": # database storage is comma delimited iem.data["wxcodes"] = presentwx.split(" ") mtr += "%s " % (presentwx, ) for _i, (skyc, _l) in enumerate(zip(skycs[i], data["skyCovLayerBase"][i])): if skyc != "": iem.data["skyc%s" % (_i + 1, )] = skyc if skyc != "CLR": iem.data["skyl%s" % (_i + 1, )] = int(_l) mtr += "%s%03i " % (skyc, int(_l) / 100) else: mtr += "CLR " t = "" tgroup = "T" val = decision(i, "temperature", 10) if val is not None: # Recall the pain enabling this # iem.data['tmpf'] = float(data['temperature'][i]) tmpc = float(data["temperatureC"][i]) t = "%s%02i/" % ( "M" if tmpc < 0 else "", tmpc if tmpc > 0 else (0 - tmpc), ) tgroup += "%s%03i" % ( "1" if tmpc < 0 else "0", (tmpc if tmpc > 0 else (0 - tmpc)) * 10.0, ) val = decision(i, "dewpoint", 10) if val is not None: # iem.data['dwpf'] = float(data['dewpoint'][i]) tmpc = float(data["dewpointC"][i]) if t != "": t = "%s%s%02i " % ( t, "M" if tmpc < 0 else "", tmpc if tmpc > 0 else 0 - tmpc, ) tgroup += "%s%03i" % ( "1" if tmpc < 0 else "0", (tmpc if tmpc > 0 else (0 - tmpc)) * 10.0, ) if len(t) > 4: mtr += t val = decision(i, "altimeter", 20) if val is not None: iem.data["alti"] = float(round(val, 2)) mtr += "A%4i " % (iem.data["alti"] * 100.0, ) mtr += "RMK " val = decision(i, "precipAccum", 25) if val is not None: if val >= 0.01: iem.data["phour"] = float(round(val, 2)) mtr += "P%04i " % (iem.data["phour"] * 100.0, ) elif val > 0: # Trace mtr += "P0000 " iem.data["phour"] = TRACE_VALUE if tgroup != "T": mtr += "%s " % (tgroup, ) if autoremarks[i] != "" or opremarks[i] != "": mtr += "%s %s " % (autoremarks[i], opremarks[i]) mtr += "MADISHF" # Eat our own dogfood try: Metar.Metar(mtr) iem.data["raw"] = mtr except Exception as exp: print("dogfooding extract_hfmetar %s resulted in %s" % (mtr, exp)) continue for key in iem.data: if isinstance(iem.data[key], np.float32): print("key: %s type: %s" % (key, type(iem.data[key]))) icursor = pgconn.cursor() if not iem.save(icursor, force_current_log=True, skip_current=True): print(("extract_hfmetar: unknown station? %s %s %s\n%s") % (sid3, network, ts, mtr)) icursor.close() pgconn.commit()
def report(vis_group): """(Macro) Return Metar object for a report with the vis group.""" return Metar.Metar(sta_time + "09010KT " + vis_group)
def report(vis_group): """(Macro) Return Metar object for a report given visibility group.""" return Metar.Metar(sta_time + "09010KT " + vis_group)
def report(runway_state): """(Macro) Return Metar object for a report containing the given runway state group""" sample_metar = 'EGNX 191250Z VRB03KT 9999 -RASN FEW008 SCT024 BKN046 M01/M03 Q0989 ' return Metar.Metar(sample_metar+' '+runway_state)
client = mqtt.Client("metar") # create new instance client.connect(broker_address) # connect to broker client.publish(MQTT_PUB_ROOT, payload=json.dumps(dict)) # publish for name in stations: url = "%s/%s.TXT" % (BASE_URL, name) try: urlh = urlopen(url) report = "" for line in urlh: if not isinstance(line, str): line = line.decode() # convert Python3 bytes buffer to string if line.startswith(name): report = line.strip() obs = Metar.Metar(line) temp = obs.temp._value * units.degC dewp = obs.dewpt._value * units.degC hum = truncate( (mpcalc.relative_humidity_from_dewpoint(temp, dewp)).m * 100, 2) # convert to % pressure = truncate(obs.press._value*33.864, 2) mqtt_publish(obs.station_id, obs.dewpt._value, obs.temp._value, hum, pressure) break if not report: print("No data for ", name, "\n\n") except Metar.ParserError as exc: print("METAR code: ", line) print(string.join(exc.args, ", "), "\n") except: import traceback
def test_011_parseType_legal(self): """Check parsing of the report type.""" self.assertEqual( Metar.Metar("METAR").type, "METAR" ) self.assertEqual( Metar.Metar("SPECI").type, "SPECI" ) self.raisesParserError("TAF" )
def test_020_parseStation_legal(self): """Check parsing of the station code.""" self.assertEqual( Metar.Metar("KEWR").station_id, "KEWR" ) self.assertEqual( Metar.Metar("METAR KEWR").station_id, "KEWR" ) self.assertEqual( Metar.Metar("BIX1").station_id, "BIX1" ) self.assertEqual( Metar.Metar("K256").station_id, "K256" )
def test_010_parseType_default(self): """Check default value of the report type.""" self.assertEqual( Metar.Metar("KEWR").type, "METAR" )
def test_140_parseWind(self): """Check parsing of wind groups.""" report = Metar.Metar(sta_time+"09010KT" ) assert report.decode_completed self.assertEqual( report.wind_dir.value(), 90 ) self.assertEqual( report.wind_speed.value(), 10 ) self.assertEqual( report.wind_gust, None ) self.assertEqual( report.wind_dir_from, None ) self.assertEqual( report.wind_dir_from, None ) self.assertEqual( report.wind(), "E at 10 knots" ) report = Metar.Metar(sta_time+"09010MPS" ) assert report.decode_completed self.assertEqual( report.wind_speed.value(), 10 ) self.assertEqual( report.wind_speed.value("KMH"), 36 ) self.assertEqual( report.wind(), "E at 19 knots" ) self.assertEqual( report.wind("MPS"), "E at 10 mps" ) self.assertEqual( report.wind("KMH"), "E at 36 km/h" ) report = Metar.Metar(sta_time+"09010KMH" ) assert report.decode_completed self.assertEqual( report.wind_speed.value(), 10 ) self.assertEqual( report.wind(), "E at 5 knots" ) self.assertEqual( report.wind('KMH'), "E at 10 km/h" ) report = Metar.Metar(sta_time+"090010KT" ) assert report.decode_completed self.assertEqual( report.wind_dir.value(), 90 ) self.assertEqual( report.wind_speed.value(), 10 ) report = Metar.Metar(sta_time+"000000KT" ) assert report.decode_completed self.assertEqual( report.wind_dir.value(), 0 ) self.assertEqual( report.wind_speed.value(), 0 ) self.assertEqual( report.wind(), "calm" ) report = Metar.Metar(sta_time+"VRB03KT" ) assert report.decode_completed self.assertEqual( report.wind_dir, None ) self.assertEqual( report.wind_speed.value(), 3 ) self.assertEqual( report.wind(), "variable at 3 knots" ) report = Metar.Metar(sta_time+"VRB00KT" ) assert report.decode_completed self.assertEqual( report.wind(), "calm" ) report = Metar.Metar(sta_time+"VRB03G40KT" ) assert report.decode_completed self.assertEqual( report.wind_dir, None ) self.assertEqual( report.wind_speed.value(), 3 ) self.assertEqual( report.wind_gust.value(), 40 ) self.assertEqual( report.wind_dir_from, None ) self.assertEqual( report.wind_dir_to, None ) self.assertEqual( report.wind(), "variable at 3 knots, gusting to 40 knots" ) report = Metar.Metar(sta_time+"21010G30KT" ) assert report.decode_completed self.assertEqual( report.wind(), "SSW at 10 knots, gusting to 30 knots" ) report = Metar.Metar(sta_time+"21010KT 180V240" ) self.assertEqual( report.wind_dir.value(), 210 ) self.assertEqual( report.wind_speed.value(), 10 ) self.assertEqual( report.wind_gust, None ) self.assertEqual( report.wind_dir_from.value(), 180 ) self.assertEqual( report.wind_dir_to.value(), 240 ) self.assertEqual( report.wind(), "S to WSW at 10 knots" )
def test_041_parseModifier(self): """Check parsing of 'modifier' groups.""" self.assertEqual( Metar.Metar(sta_time+"AUTO").mod, "AUTO" ) self.assertEqual( Metar.Metar(sta_time+"COR").mod, "COR" )
def test_issue139_no_wind_unit(): """Check the default wind speed units for international sites.""" report = Metar.Metar("CXXX 101651Z 09010G20") assert report.wind_speed.string() == "10 mps"
# from __future__ import print_function from metar import Metar # A sample METAR report code = "METAR KEWR 111851Z VRB03G19KT 2SM R04R/3000VP6000FT TSRA BR FEW015 BKN040CB BKN065 OVC200 22/22 A2987 RMK AO2 PK WND 29028/1817 WSHFT 1812 TSB05RAB22 SLP114 FRQ LTGICCCCG TS OHD AND NW-N-E MOV NE P0013 T02270215" print( "-----------------------------------------------------------------------") print("METAR: ", code) print( "-----------------------------------------------------------------------") # Initialize a Metar object with the coded report obs = Metar.Metar(code) # Print the individual data # The 'station_id' attribute is a string. print("station: %s" % obs.station_id) if obs.type: print("type: %s" % obs.report_type()) # The 'time' attribute is a datetime object if obs.time: print("time: %s" % obs.time.ctime()) # The 'temp' and 'dewpt' attributes are temperature objects if obs.temp:
def test_issue51_strict(): """Check that setting strict=False prevents a ParserError""" with warnings.catch_warnings(record=True) as w: report = Metar.Metar(sta_time + "90010KT", strict=False) assert len(w) == 1 assert report.wind_speed is None
'KIAH', 'KDEN', 'KMBS', 'KRST', 'KJAX', 'KPBI', 'KSNA', 'KFAR', 'KELP', 'KCHS', 'KCWA', 'KFWA', 'KSBN', 'KSAT', 'KCMH', 'KIND', 'KCID', 'KBMI', 'KMIA', 'KBWI', 'KPIT', 'KCMX', 'KLAN', 'KGSP', 'KLSE', 'KSGF', 'KTOL', 'KOMA', 'KTPA', 'KPWM', 'KTVC', 'KHPN', 'KDLH', 'KSAN', 'KSRQ', 'KEWR', 'KROC', 'KPDX', 'KORF', 'KMKG', 'KSPI', 'KMSN', 'KATL', 'KCOU', 'KDSM', 'KILM', 'KROA', 'KMEM', 'KHSV', 'KSLC', 'KLEX', 'KSDF', 'KEVV', 'KFSD', 'KDTW', 'KBOS', 'KSYR', 'KASE', 'KPHX', 'KMCI', 'KLIT' ] for airport in airports: try: cxn = mysql.connector.connect(host='146.148.73.209', user='******', db='METAR') raw_metar = fetch(airport) parsed_metar = Metar.Metar(raw_metar) metar_data = { 'Type': parsed_metar.type, 'Mode': parsed_metar.mod, 'StationID': parsed_metar.station_id, 'Time': parsed_metar.time, 'Cycle': parsed_metar.cycle, 'WindDirection': parsed_metar.wind_dir.value() if parsed_metar.wind_dir else None, 'WindSpeed': parsed_metar.wind_speed.value('KT') if parsed_metar.wind_speed else None, 'WindGust': parsed_metar.wind_gust.value('KT') if parsed_metar.wind_gust else None, 'WindDirectionFrom': parsed_metar.wind_dir_from.value() if parsed_metar.wind_dir_from else None, 'WindDirectionTo': parsed_metar.wind_dir_to.value() if parsed_metar.wind_dir_to else None, 'Visibility': parsed_metar.vis.value('SM') if parsed_metar.vis else None, 'VisibilityDirection': parsed_metar.vis_dir.value() if parsed_metar.vis_dir else None, 'MaxVisibility': parsed_metar.max_vis.value('SM') if parsed_metar.max_vis else None,
def report_nowind(vis_group): """(Macro) Return Metar object for a report containing the given visibility group, without a preceeding wind group. """ return Metar.Metar(sta_time + vis_group)
print ("Nav Category:\t\t%s" % (iflight) ) print ("Sky Condition:\t\t%s" % (skycond) ) print ('Visibility [{}]:\t{}'.format(visi_unit, round(skyvisi,1)) ) # Need to truncate decimals print ("Wind:\t\t\t%s [km/h] %s (%s\xb0)" % (yellow(windspd), winddir, winddeg) ) print ("Temperature [\xb0C]:\t%s" % (tempc) ) print ("Dew Point [\xb0C]:\t\t%s" % (tempd) ) print ("Pressure [mbar=hPa]:\t%s" % (press) ) print ("Humidity [%%]:\t\t%s" % (humid) ) #------------------------------------------------ # METAR "-m <airport-iata>" #------------------------------------------------ if query == 5 : metar = blist['metar'] obs = Metar.Metar(metar) #HLine = ('{:8>} {}'.format(airport, '(Work in progress!)') ) Hleng = 80 # len(HLine) print ('\nMETAR INFO for {}'.format(yellow(airport)) ) print ("-"*Hleng) #print (HLine) #print ("-"*Hleng) #for k, v in obs: # print('{:20>} {}'.format(k,v)) print(obs.string()) #------------------------------------------------
def report(runway_state): """(Macro) Return Metar object for given runway state group""" sample_metar = ("EGNX 191250Z VRB03KT 9999 -RASN FEW008 SCT024 " "BKN046 M01/M03 Q0989 ") return Metar.Metar(sample_metar + " " + runway_state)
def test_issue26_runway_slashes(RVR): """Check RVR with slashes decoding.""" report = Metar.Metar( "METAR KPIT 091955Z COR 22015G25KT 3/4SM R28L/2600FT {} TSRA OVC010CB " "18/16 A2992 RMK SLP045 T1820160".format(RVR)) assert len(report.runway) == 1
def report(sky_conditions): """(Macro) Return Metar object for the given sky conditions.""" sample_metar = "{} 14005KT 6000 {} M05/M10 Q1018".format( sta_time, sky_conditions) return Metar.Metar(sample_metar)
def test_010_parseType_default(): """Check default value of the report type.""" assert Metar.Metar("KEWR").type == "METAR"
def process(ncfn): """Process this file """ IEM = psycopg2.connect(database='iem', host='iemdb') icursor = IEM.cursor() xref = {} icursor.execute("""SELECT id, network from stations where network ~* 'ASOS' or network = 'AWOS' and country = 'US'""") for row in icursor: xref[row[0]] = row[1] icursor.close() nc = netCDF4.Dataset(ncfn) data = {} for vname in [ 'stationId', 'observationTime', 'temperature', 'dewpoint', 'altimeter', # Pa 'windDir', 'windSpeed', # mps 'windGust', 'visibility', # m 'precipAccum', 'presWx', 'skyCvr', 'skyCovLayerBase', 'autoRemark', 'operatorRemark' ]: data[vname] = nc.variables[vname][:] vname += "QCR" if vname in nc.variables: data[vname] = nc.variables[vname][:] for vname in ['temperature', 'dewpoint']: data[vname + "C"] = temperature(data[vname], 'K').value('C') data[vname] = temperature(data[vname], 'K').value('F') for vname in ['windSpeed', 'windGust']: data[vname] = speed(data[vname], 'MPS').value('KT') data['altimeter'] = pressure(data['altimeter'], 'PA').value("IN") data['skyCovLayerBase'] = distance(data['skyCovLayerBase'], 'M').value("FT") data['visibility'] = distance(data['visibility'], 'M').value("MI") data['precipAccum'] = distance(data['precipAccum'], 'MM').value("IN") for i in range(len(data['stationId'])): sid = tostring(data['stationId'][i]) sid3 = sid[1:] if sid[0] == 'K' else sid ts = datetime.datetime(1970, 1, 1) + datetime.timedelta( seconds=data['observationTime'][i]) ts = ts.replace(tzinfo=pytz.timezone("UTC")) mtr = "%s %sZ AUTO " % (sid, ts.strftime("%d%H%M")) network = xref.get(sid3, 'ASOS') iem = Observation(sid3, network, ts.astimezone(TIMEZONES[LOC2TZ.get(sid3, None)])) # 06019G23KT if (data['windDirQCR'][i] == 0 and data['windDir'][i] is not np.ma.masked): iem.data['drct'] = int(data['windDir'][i]) mtr += "%03i" % (iem.data['drct'], ) else: mtr += "///" if (data['windSpeedQCR'][i] == 0 and data['windSpeed'][i] is not np.ma.masked): iem.data['sknt'] = int(data['windSpeed'][i]) mtr += "%02i" % (iem.data['sknt'], ) else: mtr += "//" if (data['windGustQCR'][i] == 0 and data['windGust'][i] is not np.ma.masked and data['windGust'][i] > 0): iem.data['gust'] = int(data['windGust'][i]) mtr += "G%02i" % (iem.data['gust'], ) mtr += "KT " if (data['visibilityQCR'][i] == 0 and data['visibility'][i] is not np.ma.masked): iem.data['vsby'] = float(data['visibility'][i]) mtr += "%sSM " % (vsbyfmt(iem.data['vsby']), ) presentwx = tostring(data['presWx'][i]) if presentwx != '': iem.data['presentwx'] = presentwx mtr += "%s " % (presentwx, ) for _i, (_c, _l) in enumerate( zip(data['skyCvr'][i], data['skyCovLayerBase'][i])): if tostring(_c) != '': skyc = tostring(_c) iem.data['skyc%s' % (_i + 1, )] = skyc if skyc != 'CLR': iem.data['skyl%s' % (_i + 1, )] = int(_l) mtr += "%s%03i " % (tostring(_c), int(_l) / 100) else: mtr += "CLR " t = "" tgroup = "T" if (data['temperatureQCR'][i] == 0 and data['temperature'][i] is not np.ma.masked): # iem.data['tmpf'] = float(data['temperature'][i]) tmpc = float(data['temperatureC'][i]) t = "%s%02i/" % ("M" if tmpc < 0 else "", tmpc if tmpc > 0 else (0 - tmpc)) tgroup += "%s%03i" % ("1" if tmpc < 0 else "0", (tmpc if tmpc > 0 else (0 - tmpc)) * 10.) if (data['dewpointQCR'][i] == 0 and data['dewpoint'][i] is not np.ma.masked): # iem.data['dwpf'] = float(data['dewpoint'][i]) tmpc = float(data['dewpointC'][i]) if t != "": t = "%s%s%02i " % (t, "M" if tmpc < 0 else "", tmpc if tmpc > 0 else 0 - tmpc) tgroup += "%s%03i" % ("1" if tmpc < 0 else "0", (tmpc if tmpc > 0 else (0 - tmpc)) * 10.) if len(t) > 4: mtr += t if (data['altimeterQCR'][i] == 0 and data['altimeter'][i] is not np.ma.masked): iem.data['alti'] = round(data['altimeter'][i], 2) mtr += "A%4i " % (iem.data['alti'] * 100., ) mtr += "RMK " if (data['precipAccumQCR'][i] == 0 and data['precipAccum'][i] is not np.ma.masked): if data['precipAccum'][i] >= 0.01: iem.data['phour'] = round(data['precipAccum'][i], 2) mtr += "P%04i " % (iem.data['phour'] * 100., ) elif data['precipAccum'][i] < 0.01 and data['precipAccum'][i] > 0: # Trace mtr += "P0000 " iem.data['phour'] = 0.0001 if tgroup != "T": mtr += "%s " % (tgroup, ) autoremark = tostring(data['autoRemark'][i]) opremark = tostring(data['operatorRemark'][i]) if autoremark != '' or opremark != '': mtr += "%s %s " % (autoremark, opremark) mtr += "MADISHF" # Eat our own dogfood try: Metar(mtr) iem.data['raw'] = mtr except: pass icursor = IEM.cursor() if not iem.save(icursor, force_current_log=True, skip_current=True): print(("extract_hfmetar: unknown station? %s %s %s\n%s") % (sid3, network, ts, mtr)) pass icursor.close() IEM.commit()
def test_140_parseWind(): """Check parsing of wind groups.""" report = Metar.Metar(sta_time + "09010KT") assert report.decode_completed assert report.wind_dir.value() == 90 assert report.wind_speed.value() == 10 assert report.wind_gust is None assert report.wind_dir_from is None assert report.wind_dir_from is None assert report.wind() == "E at 10 knots" report = Metar.Metar(sta_time + "09010MPS") assert report.decode_completed assert report.wind_speed.value() == 10 assert report.wind_speed.value("KMH") == 36 assert report.wind() == "E at 19 knots" assert report.wind("MPS") == "E at 10 mps" assert report.wind("KMH") == "E at 36 km/h" report = Metar.Metar(sta_time + "09010KMH") assert report.decode_completed assert report.wind_speed.value() == 10 assert report.wind() == "E at 5 knots" assert report.wind("KMH") == "E at 10 km/h" report = Metar.Metar(sta_time + "090010KT") assert report.decode_completed assert report.wind_dir.value() == 90 assert report.wind_speed.value() == 10 report = Metar.Metar(sta_time + "000000KT") assert report.decode_completed assert report.wind_dir.value() == 0 assert report.wind_speed.value() == 0 assert report.wind() == "calm" report = Metar.Metar(sta_time + "VRB03KT") assert report.decode_completed assert report.wind_dir is None assert report.wind_speed.value() == 3 assert report.wind() == "variable at 3 knots" report = Metar.Metar(sta_time + "VRB00KT") assert report.decode_completed assert report.wind() == "calm" report = Metar.Metar(sta_time + "VRB03G40KT") assert report.decode_completed assert report.wind_dir is None assert report.wind_speed.value() == 3 assert report.wind_gust.value() == 40 assert report.wind_dir_from is None assert report.wind_dir_to is None assert report.wind() == "variable at 3 knots, gusting to 40 knots" report = Metar.Metar(sta_time + "21010G30KT") assert report.decode_completed assert report.wind() == "SSW at 10 knots, gusting to 30 knots" report = Metar.Metar(sta_time + "21010KT 180V240") assert report.wind_dir.value() == 210 assert report.wind_speed.value() == 10 assert report.wind_gust is None assert report.wind_dir_from.value() == 180 assert report.wind_dir_to.value() == 240 assert report.wind() == "S to WSW at 10 knots"
def test_040_parseModifier_default(): """Check default 'modifier' value.""" assert Metar.Metar("KEWR").mod == "AUTO"
def report(wind_group): """(Macro) Return Metar object from parsing the given wind group.""" return Metar.Metar(sta_time + wind_group)
def report(mod_group): """(Macro) Return Metar object from parsing the modifier group.""" return Metar.Metar(sta_time + mod_group)
def __init__(self, conf): self.conf = conf self.lastgrib = self.conf.lastgrib self.wafs = WAFS(conf) self.metar = Metar(conf) threading.Thread.__init__(self)