def parseMetar(self, icao, metar, airport_msl = 0):
     ''' Parse metar'''
     
     weather = {
                'icao': icao,
                'metar': metar,
                'elevation': airport_msl,
                'wind': [0, 0, 0], # Heading, speed, shear
                'variable_wind': False,
                'clouds': [0, 0, False] * 3, # Alt, coverage type
                'temperature': [False, False], # Temperature, dewpoint
                'pressure': False, # space c.pa2inhg(10.1325),
                'visibility': 9998,
                'precipitation': {},
                }
     
     metar = metar.split('TEMPO')[0]
     
     clouds = []
     
     for cloud in self.RE_CLOUD.findall(metar):
         coverage, alt, type = cloud
         alt = float(alt) * 30.48 + airport_msl 
         clouds.append([alt, coverage, type])
     
     weather['clouds'] = clouds
     
     m = self.RE_PRESSURE.search(metar)
     if m:
         unit, press = m.groups()
         press = float(press)
         
         if unit:
             if unit == 'A':
                 press = press/100
             elif unit == 'SLP':
                 if press > 500:
                     press = c.pa2inhg((press / 10 + 900) * 100)
                 else:
                     press = c.pa2inhg((press / 10 + 1000) * 100)
             elif unit == 'Q':
                 press = c.pa2inhg(press * 100)
         
         if 25 < press < 35:
             weather['pressure'] = press
     
     m = self.RE_TEMPERATURE2.search(metar)
     if m:
         tp, temp, dp, dew = m.groups()
         temp = float(temp) * 0.1
         dew = float(dew) * 0.1
         if tp == '1': temp *= -1
         if dp == '1': dew *= -1
         weather['temperature'] = [temp, dew]  
     else:  
         m = self.RE_TEMPERATURE.search(metar)
         if m:
             temps, temp, dews, dew = m.groups()
             temp = int(temp)
             dew = int(dew)
             if dews: dew *= -1
             if temps: temp *= -1
             weather['temperature'] = [temp, dew]
     
     m = self.RE_VISIBILITY.search(metar)
     if m:
         if m.group(0) == 'CAVOK' or (m.group(0)[0] == 'P' and int(m.group(2)) > 7999):
             visibility = 9999
         else:
             visibility = 0
             
             vis0, vis1, vis2, vis3, div, unit = m.groups()
             
             if vis1: visibility += int(vis1)
             if vis2: visibility += int(vis2)
             if vis3:
                 vis3 = int(vis3)
                 if div:
                     vis3 /= float(div[1:])
                 visibility += vis3
             if unit == 'SM': visibility *= 1609.34
             if unit == 'KM': visibility *= 1000
         
         weather['visibility'] = visibility
     
     m = self.RE_WIND.search(metar)
     if m:
         heading, speed, gust, unit = m.groups()
         if heading == 'VRB':
             heading = 0
             weather['variable_wind'] = [0, 360]
         else:
             heading = int(heading)
         
         speed = int(speed)
         if not gust: 
             gust = 0
         else:
             gust = int(gust[1:]) - speed
         
         if unit in ('MPS', 'MPH'):
             speed = c.ms2knots(speed)
             gust = c.ms2knots(gust)
             if unit == 'MPH':
                 speed /= 60
                 gust  /= 60
         if unit == 'KMH':
             speed = c.m2kn(speed / 1000.0)
             gust = c.m2kn(gust / 1000.0)
                             
         weather['wind'] = [heading, speed, gust]
     
     m = self.RE_VARIABLE_WIND.search(metar)
     if m:
         h1, h2 = m.groups()
         weather['variable_wind'] = [int(h1), int(h2)]
         
     precipitation = {}
     for precp in self.RE_PRECIPITATION.findall(metar):
         intensity, recent, mod, kind, neg = precp
         if neg == 'E':
             recent = 'RE'
         if neg != 'NO':
             precipitation[kind] = {'int': intensity ,'mod': mod, 'recent': recent}
         
     weather['precipitation'] = precipitation
     
     # Extended visibility
     if weather['visibility'] > 9998:
         weather['mt_visibility'] = weather['visibility']
         ext_vis = c.rh2visibility(c.dewpoint2rh(weather['temperature'][0], weather['temperature'][1]))
         if ext_vis > weather['visibility']:
             weather['visibility'] = int(ext_vis)
     
     return weather
Example #2
0
    def parseMetar(self, icao, metar, airport_msl=0):
        ''' Parse metar'''

        weather = {
            'icao': icao,
            'metar': metar,
            'elevation': airport_msl,
            'wind': [0, 0, 0],  # Heading, speed, shear
            'variable_wind': False,
            'clouds': [0, 0, False] * 3,  # Alt, coverage type
            'temperature': [False, False],  # Temperature, dewpoint
            'pressure': False,  # space c.pa2inhg(10.1325),
            'visibility': 9998,
            'precipitation': {},
        }

        metar = metar.split('TEMPO')[0]

        clouds = []

        for cloud in self.RE_CLOUD.findall(metar):
            coverage, alt, type = cloud
            alt = float(alt) * 30.48 + airport_msl
            clouds.append([alt, coverage, type])

        weather['clouds'] = clouds

        m = self.RE_PRESSURE.search(metar)
        if m:
            unit, press = m.groups()
            press = float(press)

            if unit:
                if unit == 'A':
                    press = press / 100
                elif unit == 'SLP':
                    if press > 500:
                        press = c.pa2inhg((press / 10 + 900) * 100)
                    else:
                        press = c.pa2inhg((press / 10 + 1000) * 100)
                elif unit == 'Q':
                    press = c.pa2inhg(press * 100)

            if 25 < press < 35:
                weather['pressure'] = press

        m = self.RE_TEMPERATURE2.search(metar)
        if m:
            tp, temp, dp, dew = m.groups()
            temp = float(temp) * 0.1
            dew = float(dew) * 0.1
            if tp == '1': temp *= -1
            if dp == '1': dew *= -1
            weather['temperature'] = [temp, dew]
        else:
            m = self.RE_TEMPERATURE.search(metar)
            if m:
                temps, temp, dews, dew = m.groups()
                temp = int(temp)
                dew = int(dew)
                if dews: dew *= -1
                if temps: temp *= -1
                weather['temperature'] = [temp, dew]

        metar = metar.split('RMK')[0]

        m = self.RE_VISIBILITY.search(metar)
        if m:
            if m.group(0) == 'CAVOK' or (m.group(0)[0] == 'P'
                                         and int(m.group(2)) > 7999):
                visibility = 9999
            else:
                visibility = 0

                vis0, vis1, vis2, vis3, div, unit = m.groups()

                if vis1: visibility += int(vis1)
                if vis2: visibility += int(vis2)
                if vis3:
                    vis3 = int(vis3)
                    if div:
                        vis3 /= float(div[1:])
                    visibility += vis3
                if unit == 'SM': visibility *= 1609.34
                if unit == 'KM': visibility *= 1000

            weather['visibility'] = visibility

        m = self.RE_WIND.search(metar)
        if m:
            heading, speed, gust, unit = m.groups()
            if heading == 'VRB':
                heading = 0
                weather['variable_wind'] = [0, 360]
            else:
                heading = int(heading)

            speed = int(speed)
            if not gust:
                gust = 0
            else:
                gust = int(gust[1:]) - speed

            if unit in ('MPS', 'MPH'):
                speed = c.ms2knots(speed)
                gust = c.ms2knots(gust)
                if unit == 'MPH':
                    speed /= 60
                    gust /= 60
            if unit == 'KMH':
                speed = c.m2kn(speed / 1000.0)
                gust = c.m2kn(gust / 1000.0)

            weather['wind'] = [heading, speed, gust]

        m = self.RE_VARIABLE_WIND.search(metar)
        if m:
            h1, h2 = m.groups()
            weather['variable_wind'] = [int(h1), int(h2)]

        precipitation = {}
        for precp in self.RE_PRECIPITATION.findall(metar):
            intensity, recent, mod, kind, neg = precp
            if neg == 'E':
                recent = 'RE'
            if neg != 'NO':
                precipitation[kind] = {
                    'int': intensity,
                    'mod': mod,
                    'recent': recent
                }

        weather['precipitation'] = precipitation

        # Extended visibility
        if weather['visibility'] > 9998:
            weather['mt_visibility'] = weather['visibility']
            ext_vis = c.rh2visibility(
                c.dewpoint2rh(weather['temperature'][0],
                              weather['temperature'][1]))
            if ext_vis > weather['visibility']:
                weather['visibility'] = int(ext_vis)

        return weather