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
def parseGribData(self, filepath, lat, lon): ''' Executes wgrib2 and parses its output ''' args = ['-s', '-lon', '%f' % (lon), '%f' % (lat), os.sep.join([self.conf.cachepath, filepath]) ] if self.conf.spinfo: p = subprocess.Popen([self.conf.wgrib2bin] + args, stdout=subprocess.PIPE, startupinfo=self.conf.spinfo, shell=True) else: p = subprocess.Popen([self.conf.wgrib2bin] + args, stdout=subprocess.PIPE) it = iter(p.stdout) data = {} clouds = {} pressure = False for line in it: r = line[:-1].split(':') # Level, variable, value level, variable, value = [r[4].split(' '), r[3], r[7].split(',')[2].split('=')[1]] if len(level) > 1: if level[1] == 'cloud': #cloud layer clouds.setdefault(level[0], {}) if len(level) > 3 and variable == 'PRES': clouds[level[0]][level[2]] = value else: #level coverage/temperature clouds[level[0]][variable] = value elif level[1] == 'mb': # wind levels data.setdefault(level[0], {}) data[level[0]][variable] = value elif level[0] == 'mean': if variable == 'PRMSL': pressure = c.pa2inhg(float(value)) windlevels = [] cloudlevels = [] # Let data ready to push on datarefs. # Convert wind levels for level in data: wind = data[level] if 'UGRD' in wind and 'VGRD' in wind: hdg, vel = c.c2p(float(wind['UGRD']), float(wind['VGRD'])) #print wind['UGRD'], wind['VGRD'], float(wind['UGRD']), float(wind['VGRD']), hdg, vel alt = c.mb2alt(float(level)) # Optional varialbes temp, rh, dew = False, False, False # Temperature if 'TMP' in wind: temp = float(wind['TMP']) # Relative Humidity if 'RH' in wind: rh = float(wind['RH']) else: temp = False if temp and rh: dew = c.dewpoint(temp, rh) windlevels.append([alt, hdg, c.ms2knots(vel), {'temp': temp, 'rh': rh, 'dew': dew, 'gust': 0}]) #print 'alt: %i rh: %i vis: %i' % (alt, float(wind['RH']), vis) # Convert cloud level for level in clouds: level = clouds[level] if 'top' in level and 'bottom' in level and 'TCDC' in level: top, bottom, cover = float(level['top']), float(level['bottom']), float(level['TCDC']) #print "XPGFS: top: %.0fmbar %.0fm, bottom: %.0fmbar %.0fm %d%%" % (top * 0.01, c.mb2alt(top * 0.01), bottom * 0.01, c.mb2alt(bottom * 0.01), cover) #if bottom > 1 and alt > 1: cloudlevels.append([c.mb2alt(bottom * 0.01) * 0.3048, c.mb2alt(top * 0.01) * 0.3048, cover]) #XP10 #cloudlevels.append((c.mb2alt(bottom * 0.01) * 0.3048, c.mb2alt(top * 0.01) * 0.3048, cover/10)) windlevels.sort() cloudlevels.sort() data = { 'winds': windlevels, 'clouds': cloudlevels, 'pressure': pressure } return data
def parseGribData(self, filepath, lat, lon): ''' Executes wgrib2 and parses its output ''' args = [ '-s', '-lon', '%f' % (lon), '%f' % (lat), os.sep.join([self.conf.cachepath, filepath]) ] if self.conf.spinfo: p = subprocess.Popen([self.conf.wgrib2bin] + args, stdout=subprocess.PIPE, startupinfo=self.conf.spinfo, shell=True) else: p = subprocess.Popen([self.conf.wgrib2bin] + args, stdout=subprocess.PIPE) it = iter(p.stdout) data = {} clouds = {} pressure = False for line in it: r = line[:-1].split(':') # Level, variable, value level, variable, value = [ r[4].split(' '), r[3], r[7].split(',')[2].split('=')[1] ] if len(level) > 1: if level[1] == 'cloud': #cloud layer clouds.setdefault(level[0], {}) if len(level) > 3 and variable == 'PRES': clouds[level[0]][level[2]] = value else: #level coverage/temperature clouds[level[0]][variable] = value elif level[1] == 'mb': # wind levels data.setdefault(level[0], {}) data[level[0]][variable] = value elif level[0] == 'mean': if variable == 'PRMSL': pressure = c.pa2inhg(float(value)) windlevels = [] cloudlevels = [] # Let data ready to push on datarefs. # Convert wind levels for level in data: wind = data[level] if 'UGRD' in wind and 'VGRD' in wind: hdg, vel = c.c2p(float(wind['UGRD']), float(wind['VGRD'])) #print wind['UGRD'], wind['VGRD'], float(wind['UGRD']), float(wind['VGRD']), hdg, vel alt = c.mb2alt(float(level)) # Optional varialbes temp, rh, dew = False, False, False # Temperature if 'TMP' in wind: temp = float(wind['TMP']) # Relative Humidity if 'RH' in wind: rh = float(wind['RH']) else: temp = False if temp and rh: dew = c.dewpoint(temp, rh) windlevels.append([ alt, hdg, c.ms2knots(vel), { 'temp': temp, 'rh': rh, 'dew': dew, 'gust': 0 } ]) #print 'alt: %i rh: %i vis: %i' % (alt, float(wind['RH']), vis) # Convert cloud level for level in clouds: level = clouds[level] if 'top' in level and 'bottom' in level and 'TCDC' in level: top, bottom, cover = float(level['top']), float( level['bottom']), float(level['TCDC']) #print "XPGFS: top: %.0fmbar %.0fm, bottom: %.0fmbar %.0fm %d%%" % (top * 0.01, c.mb2alt(top * 0.01), bottom * 0.01, c.mb2alt(bottom * 0.01), cover) #if bottom > 1 and alt > 1: cloudlevels.append([ c.mb2alt(bottom * 0.01) * 0.3048, c.mb2alt(top * 0.01) * 0.3048, cover ]) #XP10 #cloudlevels.append((c.mb2alt(bottom * 0.01) * 0.3048, c.mb2alt(top * 0.01) * 0.3048, cover/10)) windlevels.sort() cloudlevels.sort() data = { 'winds': windlevels, 'clouds': cloudlevels, 'pressure': pressure } return data
def parse_grib_data(self, filepath, lat, lon): """Executes wgrib2 and parses its output""" args = ['-s', '-lon', '%f' % (lon), '%f' % (lat), filepath ] kwargs = {'stdout': subprocess.PIPE} if self.conf.spinfo: kwargs.update({'startupinfo': self.conf.spinfo, 'shell': True}) print("Calling subprocess with {}, {}".format([self.conf.wgrib2bin] + args, kwargs)) p = subprocess.Popen([self.conf.wgrib2bin] + args, **kwargs) print("result of grib data subprocess is p={}".format(p)) it = iter(p.stdout) data = {} clouds = {} pressure = False for line in it: if sys.version_info.major == 2: r = line[:-1].split(':') else: r = line.decode('utf-8')[:-1].split(':') # Level, variable, value level, variable, value = [r[4].split(' '), r[3], r[7].split(',')[2].split('=')[1]] if len(level) > 1: if level[1] == 'cloud': # cloud layer clouds.setdefault(level[0], {}) if len(level) > 3 and variable == 'PRES': clouds[level[0]][level[2]] = value else: # level coverage/temperature clouds[level[0]][variable] = value elif level[1] == 'mb': # wind levels data.setdefault(level[0], {}) data[level[0]][variable] = value elif level[0] == 'mean': if variable == 'PRMSL': pressure = c.pa2inhg(float(value)) windlevels = [] cloudlevels = [] # Let data ready to push on datarefs. # Convert wind levels if sys.version_info.major == 2: wind_levels = data.iteritems() else: wind_levels = iter(data.items()) for level, wind in wind_levels: if 'UGRD' in wind and 'VGRD' in wind: hdg, vel = c.c2p(float(wind['UGRD']), float(wind['VGRD'])) # print wind['UGRD'], wind['VGRD'], float(wind['UGRD']), float(wind['VGRD']), hdg, vel alt = int(c.mb2alt(float(level))) # Optional varialbes temp, rh, dew = False, False, False # Temperature if 'TMP' in wind: temp = float(wind['TMP']) # Relative Humidity if 'RH' in wind: rh = float(wind['RH']) if temp and rh: dew = c.dewpoint(temp, rh) windlevels.append([alt, hdg, c.ms2knots(vel), {'temp': temp, 'rh': rh, 'dew': dew, 'gust': 0}]) # print 'alt: %i rh: %i vis: %i' % (alt, float(wind['RH']), vis) # Convert cloud level for level in clouds: level = clouds[level] if 'top' in level and 'bottom' in level and 'TCDC' in level: top, bottom, cover = float(level['top']), float(level['bottom']), float(level['TCDC']) # print "XPGFS: top: %.0fmbar %.0fm, bottom: %.0fmbar %.0fm %d%%" % (top * 0.01, c.mb2alt(top * 0.01), bottom * 0.01, c.mb2alt(bottom * 0.01), cover) # if bottom > 1 and alt > 1: cloudlevels.append([c.mb2alt(bottom * 0.01) * 0.3048, c.mb2alt(top * 0.01) * 0.3048, cover]) # XP10 # cloudlevels.append((c.mb2alt(bottom * 0.01) * 0.3048, c.mb2alt(top * 0.01) * 0.3048, cover/10)) windlevels.sort() cloudlevels.sort() data = { 'winds': windlevels, 'clouds': cloudlevels, 'pressure': pressure } return data
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
def parseGribData(self, filepath, lat, lon): """ Executes wgrib2 and parses its output """ args = ["-s", "-lon", "%f" % (lon), "%f" % (lat), os.sep.join([self.conf.cachepath, filepath])] if self.conf.spinfo: p = subprocess.Popen( [self.conf.wgrib2bin] + args, stdout=subprocess.PIPE, startupinfo=self.conf.spinfo, shell=True ) else: p = subprocess.Popen([self.conf.wgrib2bin] + args, stdout=subprocess.PIPE) it = iter(p.stdout) data = {} clouds = {} pressure = False for line in it: r = line[:-1].split(":") # Level, variable, value level, variable, value = [r[4].split(" "), r[3], r[7].split(",")[2].split("=")[1]] if len(level) > 1: if level[1] == "cloud": # cloud layer clouds.setdefault(level[0], {}) if len(level) > 3 and variable == "PRES": clouds[level[0]][level[2]] = value else: # level coverage/temperature clouds[level[0]][variable] = value elif level[1] == "mb": # wind levels data.setdefault(level[0], {}) data[level[0]][variable] = value elif level[0] == "mean": if variable == "PRMSL": pressure = c.pa2inhg(float(value)) windlevels = [] cloudlevels = [] # Let data ready to push on datarefs. # Convert wind levels for level in data: wind = data[level] if "UGRD" in wind and "VGRD" in wind: hdg, vel = c.c2p(float(wind["UGRD"]), float(wind["VGRD"])) # print wind['UGRD'], wind['VGRD'], float(wind['UGRD']), float(wind['VGRD']), hdg, vel alt = c.mb2alt(float(level)) # Optional varialbes temp, rh, dew = False, False, False # Temperature if "TMP" in wind: temp = float(wind["TMP"]) # Relative Humidity if "RH" in wind: rh = float(wind["RH"]) else: temp = False if temp and rh: dew = c.dewpoint(temp, rh) windlevels.append([alt, hdg, c.ms2knots(vel), {"temp": temp, "rh": rh, "dew": dew, "gust": 0}]) # print 'alt: %i rh: %i vis: %i' % (alt, float(wind['RH']), vis) # Convert cloud level for level in clouds: level = clouds[level] if "top" in level and "bottom" in level and "TCDC" in level: top, bottom, cover = float(level["top"]), float(level["bottom"]), float(level["TCDC"]) # print "XPGFS: top: %.0fmbar %.0fm, bottom: %.0fmbar %.0fm %d%%" % (top * 0.01, c.mb2alt(top * 0.01), bottom * 0.01, c.mb2alt(bottom * 0.01), cover) # if bottom > 1 and alt > 1: cloudlevels.append([c.mb2alt(bottom * 0.01) * 0.3048, c.mb2alt(top * 0.01) * 0.3048, cover]) # XP10 # cloudlevels.append((c.mb2alt(bottom * 0.01) * 0.3048, c.mb2alt(top * 0.01) * 0.3048, cover/10)) windlevels.sort() cloudlevels.sort() data = {"winds": windlevels, "clouds": cloudlevels, "pressure": pressure} return data