def _make_dust(weather_object, mission_weather): if mission_weather.dust_enabled: LOGGER.debug('dust found in mission') if mission_weather.dust_density < 1000: weather_object.other.append('DS') else: weather_object.other.append('PO')
def _make_clouds(weather_object) -> typing.Tuple[int, int, int]: cloud_density = 0 cloud_base = 300 cloud_thickness = 200 _layer_in_use = None for _layer in weather_object.cloud_layers: _coverage = random.randint(*CLOUD_METAR_TO_DCS[_layer.type]) # nosec if _coverage > cloud_density: cloud_density = _coverage _layer_in_use = _layer if _layer_in_use: LOGGER.debug('using cloud layer: %s', _layer_in_use.repr) if not _layer_in_use.altitude: LOGGER.warning( 'no cloud altitude data found in METAR, using random number between 5 and 35 thousand feet' ) cloud_base = random.randint(5, 25) * 1000 # nosec else: if not weather_object.metar_units.altitude == 'ft': raise ValueError(weather_object.metar_units.altitude) cloud_base = CloudBase(_layer_in_use.altitude * 100, 'ft').value('m') cloud_thickness = int(cloud_density / 10 * 2000) else: LOGGER.debug('no clouds') cloud_base = DCSWeather.normalize_cloud_base(cloud_base) cloud_thickness = DCSWeather.normalize_cloud_thickness(cloud_thickness) return cloud_base, cloud_density, cloud_thickness
def _make_fog(weather_object, mission_weather): if not mission_weather.fog_enabled: LOGGER.debug('no fog in mission, setting visibility to 9999') weather_object.visibility = Length(9999, 'm') else: LOGGER.debug('fog visibility in mission: %s', mission_weather.fog_visibility) weather_object.visibility = Length(mission_weather.fog_visibility, 'm')
def _make_turbulence(weather_object, mission_weather): if mission_weather.turbulence > 0: LOGGER.debug('turbulence found in mission') wind_speed = mission_weather.wind_ground_speed weather_object.wind_gust = WindSpeed( wind_speed + wind_speed * (mission_weather.turbulence / 10), 'm/s') weather_object.wind_speed = WindSpeed(wind_speed, 'm/s') else: LOGGER.debug('no turbulence found in mission') weather_object.wind_speed = WindSpeed( mission_weather.wind_ground_speed, 'm/s') weather_object.wind_gust = WindSpeed(0)
def _make_dust(weather_object) -> typing.Tuple[bool, int]: dust_enabled = False dust_density = 3000 for _dust_indicator in {'DU', 'DS', 'PO', 'SS'}: if any(_dust_indicator in other for other in weather_object.metar_data.other): if weather_object.visibility.value() > 5000: LOGGER.debug('there is dust in the area but visibility is over 5000m, not adding dust') break else: LOGGER.warning('there is dust in the area, visibility will be severely restricted') dust_enabled = True dust_density = DCSWeather.normalize_dust_density(weather_object.visibility.value()) break return dust_enabled, dust_density
def weather_from_icao(weather_object: WeatherABC): """ Creates a Weather object from a given ICAO :param weather_object: weather object to fill :type weather_object: WeatherABC """ LOGGER.debug('building Weather from ICAO code') weather_object.source_type = 'ICAO' weather_object.station_icao = weather_object.source.upper() weather_object.raw_metar_str = avwx.metar.fetch(weather_object.station_icao) weather_object.metar_data, weather_object.metar_units = avwx.metar.parse(weather_object.station_icao, weather_object.raw_metar_str) weather_object.fill_from_metar_data()
def _make_precipitations(weather_object, mission_weather): if mission_weather.precipitation_code == 1: LOGGER.debug('rain found in mission') weather_object.other.append('RA') if mission_weather.precipitation_code == 2: LOGGER.debug('thunderstorm found in mission') weather_object.other.append('+RATS') if mission_weather.precipitation_code == 3: LOGGER.debug('snow found in mission') weather_object.other.append('SN') if mission_weather.precipitation_code == 4: LOGGER.debug('blizzard found in mission') weather_object.other.append('+BLSN')
def apply_weather_to_mission_dict(weather_object: WeatherABC, mission: elib_miz.Mission) -> elib_miz.Mission: """ Generates a DCSWeather object from self and creates a new elib_miz.Mission object out of it :param weather_object: weather object to apply to mission dictionary :type weather_object: WeatherABC :param mission: mission to modify :type mission: elib_miz.Mission :return: new, modified mission :rtype: elib_miz.Mission """ LOGGER.info('generating DCS weather') dcs_weather = weather_object.generate_dcs_weather() new_mission_dict = copy.deepcopy(mission.d) new_mission_l10n = copy.deepcopy(mission.l10n) new_mission = elib_miz.Mission(new_mission_dict, new_mission_l10n) LOGGER.debug('DCS weather: %s', pprint.pformat(dcs_weather)) LOGGER.debug('applying weather to mission file') wxd = new_mission.weather wxd.altimeter = dcs_weather.altimeter wxd.turbulence = dcs_weather.turbulence wxd.temperature = dcs_weather.temperature wxd.wind_ground_speed = dcs_weather.wind_ground_speed wxd.wind_ground_dir = dcs_weather.wind_ground_dir wxd.wind_at2000_speed = dcs_weather.wind_2000_speed wxd.wind_at2000_dir = dcs_weather.wind_2000_dir wxd.wind_at8000_speed = dcs_weather.wind_8000_speed wxd.wind_at8000_dir = dcs_weather.wind_8000_dir wxd.precipitation_code = dcs_weather.precipitation_code wxd.cloud_base = dcs_weather.cloud_base wxd.cloud_density = dcs_weather.cloud_density wxd.cloud_thickness = dcs_weather.cloud_thickness wxd.fog_enabled = dcs_weather.fog_enabled wxd.fog_thickness = dcs_weather.fog_thickness wxd.fog_visibility = dcs_weather.fog_visibility wxd.dust_enabled = dcs_weather.dust_enabled wxd.dust_density = dcs_weather.dust_density return new_mission
def _make_date_time(weather_object, mission): LOGGER.debug('mission theatre is: %s', mission.theatre) if mission.theatre in ( elib_miz.static.Theater.caucasus, elib_miz.static.Theater.persian_gulf, ): tz_info = datetime.timezone(offset=datetime.timedelta(hours=4)) elif mission.theatre == elib_miz.static.Theater.nevada: tz_info = datetime.timezone(offset=-datetime.timedelta(hours=7)) else: raise ValueError(f'Theatre not managed: {mission.theatre}') LOGGER.debug('using offset: %s', tz_info) date_time = datetime.datetime(year=mission.year, month=mission.month, day=mission.day, hour=mission.hour, minute=mission.minute, second=mission.second, tzinfo=tz_info) utc_time = date_time.astimezone(datetime.timezone.utc) weather_object.date_time = avwx.structs.Timestamp( repr=utc_time.strftime('%H%M%SZ'), dt=utc_time, )
def weather_from_metar_string(weather_object: WeatherABC): """ Creates a Weather object from a METAR string :param weather_object: weather object to fill :type weather_object: WeatherABC """ LOGGER.debug('building Weather from METAR string') weather_object.source_type = 'METAR' LOGGER.debug('extracting station from METAR') weather_object.station_icao = utils.extract_station_from_metar_str( weather_object.source) LOGGER.debug('station: %s', weather_object.station_icao) weather_object.raw_metar_str = weather_object.source weather_object.metar_data, weather_object.metar_units = avwx.metar.parse( weather_object.station_icao, weather_object.raw_metar_str) weather_object.fill_from_metar_data()
def weather_from_metar_data(weather_object: WeatherABC): """ Builds a Weather object from METAR data as parsed by AVWX :param weather_object: weather object to build :type weather_object: WeatherABC """ LOGGER.debug('creating weather object based on METAR data') LOGGER.debug('METAR data: %s', weather_object.metar_data) LOGGER.debug('METAR units: %s', weather_object.metar_units) _make_altimeter(weather_object) _make_visibility(weather_object) weather_object.cloud_layers = [ cloud_layer for cloud_layer in weather_object.metar_data.clouds ] _make_temperature(weather_object) _make_dew_point(weather_object) _make_wind(weather_object) weather_object.date_time = weather_object.metar_data.time weather_object.other = weather_object.metar_data.other weather_object.remarks = weather_object.metar_data.remarks LOGGER.debug('resulting weather object: %s', repr(weather_object)) # pylint: disable=possibly-unused-variable
def _make_clouds( weather_object, mission_weather, ): if mission_weather.cloud_density == 0: LOGGER.debug('no cloud found in mission') weather_object.cloud_layers = [] else: LOGGER.debug('cloud density in mission: %s', mission_weather.cloud_density) cloud_type = static.CLOUD_DCS_TO_METAR[mission_weather.cloud_density] LOGGER.debug('inferred cloud type: %s', cloud_type) LOGGER.debug('cloud base in mission: %s', mission_weather.cloud_base) cloud_alt = int( round( Altitude(mission_weather.cloud_base, 'm').value('ft') / 100, 0)) LOGGER.debug('inferred cloud altitude: %s', cloud_alt) weather_object.cloud_layers = [ avwx.structs.Cloud( repr=f'{cloud_type}{cloud_alt:03d}', type=cloud_type, altitude=cloud_alt, modifier=None, ) ] LOGGER.debug('resulting cloud layer: %s', weather_object.cloud_layers)
def weather_from_miz_file(weather_object: WeatherABC): """ Creates a Weather object from a MIZ file :param weather_object: weather object to fill :type weather_object: WeatherABC """ LOGGER.debug('building Weather from MIZ file') LOGGER.debug('source MIZ file: %s', weather_object.source) weather_object.station_icao = Config.dummy_icao_code weather_object.source_type = 'MIZ file' with elib_miz.Miz(weather_object.source) as miz: mission_weather = miz.mission.weather mission = miz.mission weather_object.altimeter = Pressure(mission_weather.altimeter, 'mmhg') LOGGER.debug('altimeter: %s', weather_object.altimeter) _make_clouds(weather_object, mission_weather) _make_fog(weather_object, mission_weather) LOGGER.debug('inferred visibility: %s', weather_object.visibility) weather_object.temperature = Temperature(mission_weather.temperature, 'c') LOGGER.debug('inferred temperature: %s', weather_object.temperature) weather_object.dew_point = weather_object.temperature.make_dummy_dew_point( ) LOGGER.debug('inferred dew point: %s', weather_object.dew_point) _make_turbulence(weather_object, mission_weather) LOGGER.debug('inferred wind speed: %s', weather_object.wind_speed) LOGGER.debug('inferred wind gust: %s', weather_object.wind_gust) weather_object.wind_direction = WindDirection( mission_weather.wind_ground_dir).reverse() weather_object.wind_direction_is_variable = False weather_object.wind_direction_range = [] _make_date_time(weather_object, mission) weather_object.other = [] _make_dust(weather_object, mission_weather) _make_precipitations(weather_object, mission_weather) if weather_object.temperature.value() < 0: LOGGER.debug('freezing conditions found in mission') weather_object.other.append('FZ') LOGGER.debug('inferred others: %s', weather_object.other) weather_object.remarks = 'NOSIG' _make_metar(weather_object) # Store the original DCS weather so there's no discrepancies if we create a new one from this Weather dcs_wx = DCSWeather(altimeter=mission_weather.altimeter, turbulence=mission_weather.turbulence, temperature=mission_weather.temperature, wind_ground_speed=mission_weather.wind_ground_speed, wind_ground_dir=mission_weather.wind_ground_dir, wind_2000_speed=mission_weather.wind_at2000_speed, wind_2000_dir=mission_weather.wind_at2000_dir, wind_8000_speed=mission_weather.wind_at8000_speed, wind_8000_dir=mission_weather.wind_at8000_dir, precipitation_code=mission_weather.precipitation_code, cloud_density=mission_weather.cloud_density, cloud_base=mission_weather.cloud_base, cloud_thickness=mission_weather.cloud_thickness, fog_enabled=mission_weather.fog_enabled, fog_visibility=mission_weather.fog_visibility, fog_thickness=mission_weather.fog_thickness, dust_enabled=mission_weather.dust_enabled, dust_density=mission_weather.dust_density) weather_object.original_dcs_weather = dcs_wx