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')
示例#2
0
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)
示例#5
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')
示例#8
0
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,
    )
示例#10
0
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