User:Flyhigh/tmp
This howto describes how to setup live setting of wind aloft. This is the wind speed, direction and temperature for different altitudes. FlightGear's feature of setting current weather by using the --enable-real-weather-fetch uses METAR which only reports ground weather.
The aloft feature only works if you have bash, awk, wget and netcat on your machine. This is usually the case if you are running linux and should be no sweat for OS/X but might require some setup if you have Windows or some less feature rich operating system.
General description
The winds aloft data is available through the NOAA's National Weather Service Aviation Weather Center. The text form of this data is at http://aviationweather.gov/products/nws/all. This provides the winds aloft data in the United States.
Outside the United States, The wind aloft data is brought to you by the nice people of Jeppesen(R). Under http://www.jeppesen.com/weather a Text Weather service is provided, but requires a subscription.
When enabling the --real-weather-fetch option, FlightGear searches for the nearest airport to your present position that has a METAR service. If it finds one, it propagates the environmental settings and the station id of the airport the METAR was fetched for. A tiny add-on sends this station-id to a listening daemon program called aloftd.
The aloftd waits for input from FlightGear and interprets it as station ids. If the station id changes, it retrieves the aloft forecast from the NOAA or Jeppesen(R), parses the data, connects to the FlightGear telnet server and sets the aloft data in the property tree.
What to do
The Protocol Extension
First, we need to tell FlightGear how to broadcast the station ID of the actual METAR-station. Copy and paste the following code into a file named metarstationid.xml and save it to your data/Protocol directory.
<?xml version="1.0"?>
<PropertyList>
<comment>
<![CDATA[
Usage:
fgfs --generic=socket,out,1,localhost,5500,udp,metarstationid
]]>
</comment>
<generic>
<output>
<line_separator>newline</line_separator>
<var_separator>,</var_separator>
<chunk>
<name>metar-station-id</name>
<format>%s</format>
<type>string</type>
<node>/environment/metar/station-id</node>
</chunk>
</output>
</generic>
</PropertyList>
The FlightGear Property Setting
Set the property
/environment/params/metar-updates-winds-aloft
to false. This can be done from the command line like
--prop://environment/params/metar-updates-winds-aloft=0
The aloftd (NOAA)
Copy and paste the following code to a file named aloftd:
#!/bin/bash
#DATA BASED ON 151800Z
#VALID 160000Z FOR USE 2000-0300Z. TEMPS NEG ABV 24000
#
#FT 3000 6000 9000 12000 18000 24000 30000 34000 39000
#ABI 1925+17 2020+12 2306+07 3416-06 3011-16 262032 273342 273553
#ABQ 2510+20 2610+11 2710-09 2523-21 264636 265645 255254
#ABR 2816 2818+12 2926+04 2934-01 2747-15 2761-27 267942 258249 257148
#ACK 2814 3117+07 3023+04 3026-01 3144-13 3154-24 326540 335749 325554
#set
#/environment/config/aloft/entry[i]/elevation-ft
#/environment/config/aloft/entry[i]/wind-from-heading-deg
#/environment/config/aloft/entry[i]/wind-speed-kt
#/environment/config/aloft/entry[i]/temperature-degc
#
#guess
#/environment/config/aloft/entry[i]/dewpoint-degc
LISTEN_PORT=5123
TELNET_PORT=2323
METAR_STATION_ID="XXXX"
URL="http://aviationweather.gov/products/nws/all"
netcat -u -l -p ${LISTEN_PORT} | \
while read line; do
if [ "$line" == "$METAR_STATION_ID" ]; then
continue
fi
METAR_STATION_ID="$line"
if [ "$METAR_STATION_ID" == "XXXX" ]; then
continue
fi
echo "new ID: $METAR_STATION_ID" >&2
wget --quiet --output-document=- "${URL}" | sed '1,/FD1US1/d' | sed '/</,$d' | awk '
BEGIN {
state = 0;
delete altitudes;
printf("data\r\n");
}
/^FT [0-9]{4,} / {
state = 1;
}
/^[A-Z]{3} / {
if (state == 2 && $1 == substr(airport, 2, 3) ) {
state = 3;
}
}
{
if (state == 1) {
for (i = 3; i <= NF; i++) {
altitudes[i] = $i;
}
state = 2;
}
if (state == 3) {
first = 3;
for (i = 3 - (10 - NF); i <= NF; i++) {
if (i <= 2) {
i = 2;
first = 2;
}
altitude = altitudes[10 - (NF - i)];
token = $i;
if (length(token) == 4) {
first++;
continue;
}
wind_dir = substr(token, 1, 2) * 10;
if (wind_dir == 99) {
wind_dir == 0;
}
wind_speed = substr(token, 3, 2);
if (wind_dir >= 500) {
wind_dir -= 500;
wind_speed += 100;
}
sign = substr(token, 5, 1);
if (sign == "-" || sign == "+") {
temp = substr( token, 6, 2 );
if (sign == "-") {
temp *= -1;
}
} else {
temp = -substr( token, 5, 2 );
}
printf("set /environment/config/aloft/entry[%d]/elevation-ft %d\r\n", i - first, altitude);
printf("set /environment/config/aloft/entry[%d]/wind-from-heading-deg %d\r\n", i - first, wind_dir);
printf("set /environment/config/aloft/entry[%d]/wind-speed-kt %d\r\n", i - first, wind_speed);
printf("set /environment/config/aloft/entry[%d]/temperature-degc %d\r\n", i - first, temp);
}
state = 4;
}
}
END {
printf("quit\r\n");
}
' -v airport=$METAR_STATION_ID | netcat localhost ${TELNET_PORT}
done
Save the file to any location and make the file executable.
The aloftd (Jeppesen(R))
Copy and paste the following code to a file named aloftd (Note that the code below needs to be updated to reflect the subscription needed and therefore will not work as-is):
#!/bin/bash
#KSFO FD DATA BASED ON 190600Z.
# 3000 6000 9000 12000 15000 18000 21000 24000
#18Z 1516P07 1723P03 1732M01 1738M06 1941M11 2045M16 2148M23 2151M30
#00Z 1814P09 1819P02 1826M03 1932M08 2039M12 2246M16 2254M23 2161M30
#06Z 1713P08 1915P02 2118M03 2223M09 2229M13 2236M18 2245M25 2253M32
#12Z 1609P07 2011P03 2313M03 2420M08 2430M13 2441M19 2450M26 2458M33
#set
#/environment/config/aloft/entry[i]/elevation-ft
#/environment/config/aloft/entry[i]/wind-from-heading-deg
#/environment/config/aloft/entry[i]/wind-speed-kt
#/environment/config/aloft/entry[i]/temperature-degc
#
#guess
#/environment/config/aloft/entry[i]/dewpoint-degc
LISTEN_PORT=5123
TELNET_PORT=2323
METAR_STATION_ID="XXXX"
# FL060-390
#WX_TYPE="fd"
# FL030-240
WX_TYPE="fdl"
# FL120-500
#WX_TYPE="fdh"
URL="http://www.jetplan.com/jeppesen/weatherServlet?query=999¬amFilterName=&"
netcat -u -l -p ${LISTEN_PORT} | \
while read line; do
if [ "$line" == "$METAR_STATION_ID" ]; then
continue
fi
METAR_STATION_ID="$line"
if [ "$METAR_STATION_ID" == "XXXX" ]; then
continue
fi
echo "new ID: $METAR_STATION_ID" >&2
echo "${URL}wxType=${WX_TYPE}&wxStation=${METAR_STATION_ID}" >&2
wget --quiet --output-document=- "${URL}wxType=${WX_TYPE}&wxStation=${METAR_STATION_ID}" | awk '
BEGIN {
state=0;
count=0;
delete altitudes;
printf( "data\r\n" );
}
/FD DATA BASED ON/ {
state = 1;
count = 0;
}
/^[0-9][0-9]Z/ {
if( state == 1 )
state = 2;
}
{
if( state == 1 ) {
if( count == 1 ) {
for( i = 1; i <= NF; i++ ) {
altitudes[i] = $i;
}
}
}
if( state == 2 ) {
for( i = 2; i <= NF; i++ ) {
altitude = altitudes[i-1];
token = $i;
wind_dir = substr( token, 1, 2 ) * 10;
wind_speed = substr( token, 3, 2 );
sign = substr( token, 5, 1 );
temp = substr( token, 6, 2 );
if( sign == "M" )
temp = temp * -1;
printf( "set /environment/config/aloft/entry[%d]/elevation-ft %d\r\n", i-2, altitude );
printf( "set /environment/config/aloft/entry[%d]/wind-from-heading-deg %d\r\n", i-2, wind_dir );
printf( "set /environment/config/aloft/entry[%d]/wind-speed-kt %d\r\n", i-2, wind_speed );
printf( "set /environment/config/aloft/entry[%d]/temperature-degc %d\r\n", i-2, temp );
}
state = 3;
}
count++;
}
END {
printf( "quit\r\n" );
}
' | netcat localhost ${TELNET_PORT}
done
Save the file to any location and make the file executable.
Running FlightGear
Now start your FlightGear with the following additional options:
--generic=socket,out,0.5,localhost,5123,udp,metarstationid --telnet=2323
Open another console window and start the created script aloftd. You should see some output telling you which airport it is fetching data for.