XPLMWeather¶
To use:
import xp
This API provides access to the X-Plane enhanced weather system and requires at least X-Plane 12.04. More detailed weather, and the ability to set weather is available with 12.3.0.
All of these functions are relatively expensive, and should not be used per-frame.
Theory of Operation¶
Get Weather
getMETARForAirport(): retrieve most recent METAR for given airport. Not necessarily an accurate representation of the current simulated weather. To get current weather at airport usegetWeatherAtLocation()with the proper latitude, longitude.getWeatherAtLocation(): retrieve weather details at particular latitude, longitude. This is current simulated weather. The returned datastructure depends on which version of X-Plane you are running, where version 12.3.0 adds more data elements. You can queryxp.XPLMWeatherInfo_tto get a full description.
Set Weather
Setting weather will not change the UI “Weather Settings”, weather set via plugin “adds” to the set of information used to calculate simulated weather. One way to visualize many of these changes is to enable the X-Plane Weather Map (Developer menu). Then select “plugin METARS” Layer. You’ll see weather that has been set by (all) plugins.
For example, in the following image, you can see weather set specifically at Cambridge airport (labeled EGSC) using
setWeatherAtAirport(), and weather set to nearby locations (labeled _PLG) usingsetWeatherAtLocation(). Latitude, longitude are displayed in white along the edges of the image. Note the “Age” of the report at the bottom of each.
setWeatherAtLocation(): sets (or perhaps “injects” is better…) weather at a particular latitude, longitude. This data is further combined with otherwise existing data to result in new weather. Your weather update merely influences the current weather simulation: the more data you inject (say over a particular region) the greater the effect.setWeatherAtAirport(): sets (or perhaps “injects” is better…) weather at a particular airport. This can be interpreted as replacing a previously downloaded METAR. This data is further combined with otherwise existing data to result in new weather. Your weather update merely influences the current weather simulation.eraseWeatherAtLocation(): removes all weather effects your plugin has injected for the given location. If other plugins have changed the weather, those plugin effects are still valid.eraseWeatherAtAirport(): removes all weather effects your plugin has injected for the given airport, similar toeraseWeatherAtLocation().beginWeatherUpdate(),endWeatherUpdate(): To facilitate making multiple changes to the weather, you should bracket your changes between “begin” and “end”. This function pair also allows you to indicate your changes are incremental, and if your changes should take effect “immediately” (as might be useful on startup) or transitioned over the next few minutes. For programming convenience, we’ve included a context managerweatherUpdateContext()to avoid mis-handling an “end”.
Get Weather¶
- getMETARForAirport(airport_id)¶
- Parameters
airport_id (str) – ICAO code
- Returns
Last known METAR for airport (str)
Get the last known METAR report for an airport by ICAO code. Note that the actual weather at that airport may have evolved significantly since the last downloaded METAR. This call is not intended to be used per-frame.:
>>> xp.getMETARForAirport('KJFK') 'KJFK 111451Z 01012KT 7SM -RA OVC011 03/02 A2974 RMK AO2 SNB1356E02 SLP070 P0005 60015 T00280017 51024' >>> xp.getMETARForAirport('JFK') '' >>> xp.getMETARForAirport('KNYC') ''
Note that valid METAR codes which are not airports such as Central Park NYC (KNYC) do not return values.
Note also that “Download Real Weather” must be enabled in order for X-Plane to have downloaded any METARs. If real weather was not enabled, the query will return an empty string with no indication that real weather is disabled.:
>>> xp.getMETARForAirport('KJFK') ''
Official SDK XPLMGetMETARForAirport
- getWeatherAtLocation(latitude, longitude, altitude_m)¶
- Parameters
latitude (float) –
longitude (float) – A “nearby” location
altitude_m (float) – Altitude (MSL) in meters
- Returns
XPLMWeatherInfo_tor None on error.
Get the current weather conditions at a given location. Note that this is not effective outside the surrounding region.
This call is not intended to be used per-frame (use datarefs if at all possible instead).
Returns
Noneon error.This function will appear to execute world-wide, with latitudes +/- 90 degrees and longitudes +/- 180 degrees. However, weather outside the current region will be less accurate, due to math errors and METAR information. (There is no way of knowing the extent of the current region, so the understanding should be “nearby weather is more accurate that far-away weather”. Generally, within 50nm of current location has good accuracy.) Using values with illegal latitude/longitude range will result in a
Nonereturn value.The
XPLMWeatherInfo_t.detail_foundattribute, on a successful return, is the actual return value from X-Plane’s XPLMGetWeatherAtLocation() call. This, I’m told, indicates “if detail weather is found”, where detail weather refers to the existence of a METAR within about 50 miles of the queried location. It is not a success/failure return value of the actual XPLMWeatherInfo_t object. (Nor is it an indication of “weather in region” vs. “weather out of region”.)What to do with this
detail_foundvalue? Beats me. It won’t tell you which METAR is nearby, or which of multiple nearby METARs are used perhaps to alter the world-wide GRIB weather data. Bug Report has been filed requesting clarification.Because
detail_founddoes not indicate success or failure, XPPython3 uses a flag to attempt to detect if data is valid. (We set an internal data structure temperature to a bogus number and if post-query it is still bad, we assume data was not successfully obtained, and returnNone.)
On success,
getWeatherAtLocation()returns aXPLMWeatherInfo_tobject. See below for details or interactively usinghelp(xp.XPLMWeatherInfo_t). The WeatherInfo object includes a list of wind layersXPLMWeatherInfoWinds_t, a list of cloud layersXPLMWeatherInfoClouds_t, and a list of floats for temperature and dewpoint layers.For example:
>>> info = xp.getWeatherAtLocation(34, -117, 2000) >>> print(info) <XPLMWeatherInfo_ object> 7.9/-10.1 252@3 QNH1009 >>> info.temperature_alt 7.93484 >>> info.dewpoint_alt -10.11784 >>> info.wind_dir_alt 252.4056 >>> info.wind_speed_alt 1.4252 >>> len(info.wind_layers) 13 >>> [x.alt_msl for x in info.wind_layers] [0.0, 540.1, 988.5, 1948.3, 3010.8, 4206.5, 5572.0, 7182.3, 9160.1, 10362.9, 11887.2, 13594.1, 16179.4] >>> print(info.wind_layers[0]) <XPLMWeatherInfoWinds_t object> 175@9 at 0.0m MSL >>> print(info.wind_layers[1]) <XPLMWeatherInfoWinds_t object> 176@10 at 540.1m MSL >>> print(info.cloud_layers[1]) <XPLMWeatherInfoClouds_t object> 2.0 (50%) from 4442.0m to 5759.5m
If
coverageis zero, there are no clouds at that layer regardless of the other parameters. Just skip that layer and look at the next.Though not documented, I assume “cloud type” enumeration is the same as the
sim/weather/aircraft/cloud_typeandsim/weather/region/cloud_typedatarefs:0 = Cirrus1 = Stratus2 = Cumulus3 = Cumulo-nimbusOfficial SDK XPLMGetWeatherAtLocation
Set Weather¶
Warning
“Setting Weather” is available only with X-Plane 12.3.0 and above, which is currently in beta. There remain some bugs in the X-Plane implementation, so the following API and/or explanations may change.
The following functions are only available with X-Plane 12.3.0+. Calling them on earlier versions of X-Plane will log an error.
The weather updates you provide, be they new observation using setWeatherAt*() or removing previous observations
using eraseWeatherAt*() are transitioned over the next few minutes, unless they are surrounded with an “updateImmediately”
begin/end context. Additionally, bare setWeatherAt*() calls result in incremental updates to plugin weather data already provided
(i.e., “isIncremental”) for the given location. If you want to reset weather (“now dammit!”) use a weather context, and erase
previous updates to be sure:
>>> with xp.weatherUpdateContext(isIncremental=0, updateImmediately=1):
... xp.eraseWeatherAtLocation(34, -117)
... xp.setWeatherAtLocation(34, -117, 2000, info)
...
- setWeatherAtLocation(latitude, longitude, altitude_m, info)¶
- Parameters
latitude (float) –
longitude (float) – floating point latitude and longitude
altitude_m (float) – altitude in meters MSL, where the weather is to be changed
info (XPLMWeatherInfo_t) –
XPLMWeatherInfo_tdata structure containing requested change. Note not all element members are applicable for “set”.
Official SDK XPLMSetWeatherAtLocation
- setWeatherAtAirport(airport_id, info)¶
- Parameters
airport_id (str) – airport ID
info (XPLMWeatherInfo_t) –
XPLMWeatherInfo_tdata structure containing requested change. Note not all element members are applicable for “set”.
Official SDK XPLMSetWeatherAtAirport
- eraseWeatherAtLocation(latitude, longitude)¶
- Parameters
latitude (float) –
longitude (float) – floating point latitude and longitude
Erase all weather information provided by this plugin at the given latitude, longitude. Note if other plugins have also provide weather at this location, those changes will still be valid. It is not harmful to call
eraseWeatherAtLocation()where you have not yet provided weather.Official SDK XPLMEraseWeatherAtLocation
- eraseWeatherAtAirport(airport_id)¶
- Parameters
airport_id (str) – airport ID
Erase all weather information provided by this plugin at the given airport. Note if other plugins have also provide weather at this airport, those changes will still be valid. It is not harmful to call
eraseWeatherAtAirport()where you have not yet provided weather.Official SDK XPLMEraseWeatherAtAirport
- beginWeatherUpdate()¶
Inform the simulator that you are starting a batch update of weather information. You must call
endWeatherUpdate()prior to exiting your callback. Failure to do so will result in error and performance issues. For this reason, we suggest you useweatherUpdateContext()instead.Because this function must be used at the same time as
endWeatherUpdate(), you cannot type this function directly into the python debugger (though you can, if you place it within a function definition.) UseweatherUpdateContext()if you want to experiment within the debugger.This call is not intended to be used per-frame.
>>> def changeWeather(): ... xp.beginWeatherUpdate() ... info = xp.getWeatherAtLocation(35, -172, 100) ... info.thermal_climb += .5 ... xp.setWeatherAtLocation(35, -172, 100, info) ... xp.endWeatherUpdate() ... >>> changeWeather()
or, using the context manager:
>>> with xp.weatherUpdateContext(): ... info = xp.getWeatherAtLocation(35, -172, 100) ... info.thermal_climb += .5 ... xp.setWeatherAtLocation(35, -172, 100, info) ...
Official SDK XPLMBeginWeatherUpdate
- endWeatherUpdate(isIncremental=1, updateImmediately=0)¶
- Parameters
isIncremental (int) – Make incremental update or over-write plugin weather
updateImmediately (int) – Make changes immediately, or transition to the requested change over the next few minutes.
Inform the simulator that you are ending a batch update of weather information. Incremental updates add to any previous weather update you’ve provided. Otherwise, you will replace all of your plugin weather associated with this location. This makes is possible to only update a fraction of your weather data at any one time.
The normal mode of operation is that you are setting the weather “in the near future”. Currently this is somewhere between one and two minutes (though this may change). Setting future weather ensures that there is no sudden jump in weather conditions. In some situations, notably for an initial setup, you may want to ensure that the weather is changed instantly. To do this, set
updateImmediatelyto one.This call is not intended to be used per-frame.
Official SDK XPLMEndWeatherUpdate
- weatherUpdateContext(isIncremental=1, updateImmediately=0)¶
- Parameters
isIncremental (int) – Make incremental update or over-write plugin weather
updateImmediately (int) – Make changes immediately, or transition to the requested change over the next few minutes.
This is a context manager which can be used to enforce calling
beginWeatherUpdate()andendWeatherUpdate(). Additionally, if your code has a bug in it, we’ll catch it and applyendWeatherUpdate()to avoid catastrophe.:>>> with xp.weatherUpdateContext(updateImmediately=1): ... xp.eraseWeatherAtLocation(35, -177) ... xp.setWeatherAtLocation(35, -177, 100, info) ... xp.setWeatherAtLocation(35, -177.5, 100, info) ... xp.setWeatherAtLocation(35, -178.0, 100, info) ... >>>
Types¶
Weather data is stored within an instance of
XPLMWeatherInfo_t, which includes lists of
Each of these types are described below.
- XPLMWeatherInfo_t¶
Weather information is stored in the XPLMWeatherInfo_t type. It is represented in XPPython3 as a class.
As with most python, you can get more information about it using help(xp.XPLMWeatherInfo_t).
This type was introduced in X-Plane 12.0, and then expanded with more fields in X-Plane 12.3.0. You can use this class with any X-Plane 12.0+, though some of the fields will not have meaning unless used with 12.3.0+
Various fields within this class interact with each other. For example, the value for .dewpoint_alt is ignored unless
.dewp_layers[0] <= -100. Be sure to fully understand all of the fields to get full value.
You can create a “blank” instance of this class, including associated lists by normal python means.:
>>> info = xp.XPLMWeatherInfo_t()
The instance will be initialized to useful defaults including:
DefaultWxrRadiusNmDefaultWxrRadiusMslFtField |
Type |
Description |
Get/Set |
X_Plane_Version |
|---|---|---|---|---|
detail_found |
int |
Return value from xp.getWeatherAtLocation(). 1=’detailed weather found’. Not meaningful otherwise. |
Get |
12.0-Read |
temperature_alt |
float |
Temperature at altitude (Celsius). To set temperature, either use
‘temp_layers’, or set |
Get/Set |
12.0-Read
12.3-R/W
|
dewpoint_alt |
float |
Dewpoint at altitude (Celsius). Similar to |
Get/Set |
12.0-Read
12.3-R/W
|
pressure_alt |
float |
Pressure at altitude (Pascals). On set, should be QNH as reported by station at the ground altitude given, or set this to 0 and set sealevel pressure in ‘pressure_sl’ instead. |
Get/Set |
12.0-Read
12.3-R/W
|
precip_rate_alt |
float |
Precipitation rate at altitude (0.0 - 1.0) Ignored on set. |
Get |
12.0-Read |
wind_dir_alt |
float |
Wind direction at altitude. (0.0 - 360.0) Ignored on set. (Use wind_layers.) |
Get |
12.0-Read |
wind_spd_alt |
float |
Wind speed at altitude (meters/second). Ignored on set. (Use wind_layers.) |
Get |
12.0-Read |
turbulence_alt |
float |
Clear-air turbulence ratio at altitude. (Values to be determined) Ignored on set. (Use wind_layers) |
Get |
12.0-Read |
wave_height |
float |
Wave height (meters) |
Get/Set |
12.0-Read
12.3-R/W
|
wave_length |
float |
Wave length (meters). Ignored on set. (Derived from other data) |
Get |
12.0-Read |
wave_dir |
int |
Wave direction (waves coming from…) degrees. |
Get/Set |
12.0-Read
12.3-R/W
|
wave_speed |
float |
Wave speed (meters/second). Ignored on set. (Derived from other data.) |
Get |
12.0-Read
12.3-R/W
|
visibility |
float |
Base visibility at 0 altitude (distance in meters) |
Get/Set |
12.0-Read
12.3-R/W
|
precip_rate |
float |
Base precipitation ratio at 0 altitude. (0.0 - 1.0) |
Get/Set |
12.0-Read
12.3-R/W
|
thermal_climb |
float |
Climb rate due to thermals (meters/second) |
Get/Set |
12.0-Read
12.3-R/W
|
pressure_sl |
float |
Pressure at sealevel (Pascals). On set, this is ignored if ‘pressure_alt’ is non-zero. |
Get/Set |
12.0-Read
12.3-R/W
|
wind_layers |
list |
List of up to Not all wind layers are always defined. |
Get/Set |
12.0-Read
12.3-R/W
|
cloud_layers |
list |
List of up to Not all cloud layers are always defined. |
Get/Set |
12.0-Read
12.3-R/W
|
temp_layers |
list |
List of floats for temperature in Celsius at predefined atmosphere levels. For layer altitudes, see dataref ‘sim/weather/region/atmosphere_alt_levels_m’. On set, if temp_layers[0] <= -100., ‘temperature_alt’ is used for ground temperature and existing altitude temps are used. |
Get/Set |
12.3 |
dewp_layers |
list |
List of floats for dewpoints in Celsius at predefined atmosphere levels. For layer altitudes, see dataref ‘sim/weather/region/atmosphere_alt_levels_m’. On set, if dewp_layers[0] <= -100., ‘dewpoint_alt’ is used for ground dewpoint temperature and existing altitude dewpoints temps are used. |
Get/Set |
12.3 |
troposphere_alt |
float |
Altitude of troposphere in meters. On set, if this is 0 or lower, ‘troposphere_alt’ and ‘troposphere_temp’ will be derived from existing data. |
Get/Set |
12.3 |
troposphere_temp |
float |
Temperature in Celsius of troposphere. On set this is ignored when
|
Get/Set |
12.3 |
age |
float |
Age in seconds of this weather report. Age affects how strongly the report affects the weather. Commonly, you will set this to zero so you change will be effective. This is meaningless on read and should be zero. |
Set |
12.3 |
radius_nm |
float |
Horizontal radius of effect of this weather report, nautical miles. You need to set this to something. This is meaningless on read. |
Set |
12.3 |
max_altitude_msl_ft |
float |
Vertical radius of effect of this weather report, feet MSL. You need to set this to something. This is meaningless on read. |
Set |
12.3 |
- XPLMWeatherInfoClouds_t¶
Field |
Type |
Description |
Get/Set |
X_Plane_Version |
|---|---|---|---|---|
cloud_type |
float |
Cloud Type, effectively an enumeration:
|
Get/Set |
12.0-Read
12.3-R/W
|
coverage |
float |
Coverage radio (0.0 - 1.0) |
Get/Set |
12.0-Read
12.3-R/W
|
alt_top |
float |
Altitude of cloud top. (MSL in meters) When alt_top == alt_base, the cloud layer is undefined. |
Get/Set |
12.0-Read
12.3-R/W
|
alt_base |
float |
Altitude of cloud base. (MSL in meters) |
Get/Set |
12.0-Read
12.3 R/W
|
- XPLMWeatherInfoWinds_t¶
Field |
Type |
Description |
Get/Set |
X_Plane_Version |
|---|---|---|---|---|
alt_msl |
float |
Altitude of wind layer. (MSL in meters) (Depth of wind layer is not specified.) |
Get/Set |
12.0-Read
12.3-R/W
|
speed |
float |
Wind speed (meters/second) On set if this is
You can have defined layers above undefined layers. |
Get/Set |
12.0-Read
12.3-R/W
|
direction |
float |
Wind direction (degrees True) (0.0-360.0) |
Get/Set |
12.0-Read
12.3-R/W
|
gust_speed |
float |
Gust speed, (meters/second). This is the total speed, not the amount of increase over the wind speed. |
Get/Set |
12.0-Read
12.3-R/W
|
shear |
float |
Search arc, degrees. The wind will shear 50% of this arc in either direction from base direction. |
Get/Set |
12.0-Read
12.3-R/W
|
turbulence |
float |
Clear Air Turbulence ratio |
Get/Set |
12.0-Read
12.3-R/W
|
Constants¶
- NumWindLayers = 13¶
Length of the list of
.wind_layersinXPLMWeatherInfo_t.Official SDK XPLM_NUM_WIND_LAYERS
- NumCloudLayers = 3¶
Length of the list of
.cloud_layersinXPLMWeatherInfo_t.Official SDK XPLM_NUM_CLOUD_LAYERS
- NumTemperatureLayers = 13¶
Length of the list of
.temp_layersand.dewp_layersinXPLMWeatherInfo_t.Official SDK XPLM_NUM_TEMPERATURE_LAYERS
- WindUndefinedLayer = -1¶
Value to use as the wind speed in
.wind_layeritem to cause this layer to be ignored (i.e., “no data” vs. “zero wind”).Official SDK XPLM_NUM_UNDEFINED_LAYER
- DefaultWxrRadiusNm = 30¶
Default horizonal radius of weather data points set using XPLMSetWeatherAtLocation and XPLMSetWeatherAtAirport. Note you still need to specify this (or another) value on set.
Official SDK XPLM_DEFAULT_WXR_RADIUS_NM
- DefaultWxrRadiusMslFt = 10000¶
Default vertical radius of weather data points set using XPLMSetWeatherAtLocation and XPLMSetWeatherAtAirport. Note you still need to specify this (or another) value on set.
Official SDK XPLM_DEFAULT_WXR_RADIUS_MSL_FT
