Skip to content

Commit

Permalink
Feat/RT/Weather: nearestmetar API request
Browse files Browse the repository at this point in the history
  • Loading branch information
TwinFan committed Jul 9, 2024
1 parent 5e9f43e commit 08981db
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 22 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Data/RealTraffic/RT_API.sjson/742250820.106701
Binary file not shown.
Binary file added Data/RealTraffic/RT_API.sjson/742250820.107324
Binary file not shown.
Binary file added Data/RealTraffic/RT_API.sjson/742250820.109163
Binary file not shown.
Binary file added Data/RealTraffic/RT_API.sjson/742254202.945561
Binary file not shown.
Binary file modified Data/RealTraffic/RT_API.sjson/data
Binary file not shown.
Binary file modified Data/RealTraffic/RT_API.sjson/metaData
Binary file not shown.
Binary file modified Data/RealTraffic/RealTraffic API.pdf
Binary file not shown.
20 changes: 14 additions & 6 deletions Include/LTRealTraffic.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,19 @@

#define REALTRAFFIC_NAME "RealTraffic"

#define RT_AUTH_URL "https://rtw.flyrealtraffic.com/v3/auth"
// TODO: Return to v3 endpoint
#define RT_ENDP "dev"
#define RT_METAR_UNKN "UNKN"

#define RT_AUTH_URL "https://rtw.flyrealtraffic.com/" RT_ENDP "/auth"
#define RT_AUTH_POST "license=%s&software=%s"
#define RT_DEAUTH_URL "https://rtw.flyrealtraffic.com/v3/deauth"
#define RT_DEAUTH_URL "https://rtw.flyrealtraffic.com/" RT_ENDP "/deauth"
#define RT_DEAUTH_POST "GUID=%s"
#define RT_WEATHER_URL "https://rtw.flyrealtraffic.com/v3/weather"
#define RT_WEATHER_POST "GUID=%s&lat=%.2f&lon=%.2f&alt=%ld&airports=UNKN&querytype=locwx&toffset=%ld"
#define RT_TRAFFIC_URL "https://rtw.flyrealtraffic.com/v3/traffic"
#define RT_NEAREST_METAR_URL "https://rtw.flyrealtraffic.com/" RT_ENDP "/nearestmetarcode"
#define RT_NEAREST_METAR_POST "GUID=%s&lat=%.2f&lon=%.2f&toffset=%ld"
#define RT_WEATHER_URL "https://rtw.flyrealtraffic.com/" RT_ENDP "/weather"
#define RT_WEATHER_POST "GUID=%s&lat=%.2f&lon=%.2f&alt=%ld&airports=%s&querytype=locwx&toffset=%ld"
#define RT_TRAFFIC_URL "https://rtw.flyrealtraffic.com/" RT_ENDP "/traffic"
#define RT_TRAFFIC_POST "GUID=%s&top=%.2f&bottom=%.2f&left=%.2f&right=%.2f&querytype=locationtraffic&toffset=%ld"


Expand Down Expand Up @@ -81,9 +87,9 @@ constexpr double RT_VSI_AIRBORNE = 80.0; ///< if VSI is more than this then w
constexpr long RT_DRCT_DEFAULT_WAIT = 8000L; ///< [ms] Default wait time between traffic requests
constexpr std::chrono::seconds RT_DRCT_ERR_WAIT = std::chrono::seconds(5); ///< standard wait between errors
constexpr std::chrono::minutes RT_DRCT_WX_WAIT = std::chrono::minutes(10); ///< How often to update weather?
constexpr std::chrono::seconds RT_DRCT_WX_ERR_WAIT = std::chrono::seconds(60); ///< How long to wait after receiving an weather error?
constexpr long RT_DRCT_WX_DIST = 10L * M_per_NM; ///< Distance for which weather is considered valid, greater than that and we re-request
constexpr int RT_DRCT_MAX_WX_ERR = 5; ///< Max number of consecutive errors during initial weather requests we wait for...before not asking for weather any longer
constexpr double RT_DRCT_MAX_METAR_DIST_NM = 50.0; ///< Max distance a METAR station is considered valid...otherwise we rather use no METAR (for clouds, for example)

/// Fields in a response of a direct connection's request
enum RT_DIRECT_FIELDS_TY {
Expand Down Expand Up @@ -256,6 +262,7 @@ class RealTrafficConnection : public LTFlightDataChannel
enum RTRequestTypeTy : int {
RT_REQU_AUTH = 1, ///< Perform Authentication request
RT_REQU_DEAUTH, ///< Perform De-authentication request (closing the session)
RT_REQU_NEAREST_METAR, ///< Perform nearest METAR location request
RT_REQU_WEATHER, ///< Perform Weather request
RT_REQU_TRAFFIC, ///< Perform Traffic request
} eRequType = RT_REQU_AUTH; ///< Which type of request is being performed now?
Expand All @@ -271,6 +278,7 @@ class RealTrafficConnection : public LTFlightDataChannel
double QNH = NAN; ///< baro pressure
std::chrono::steady_clock::time_point next; ///< next time to request RealTraffic weather
positionTy pos; ///< viewer position for which we received Realtraffic weather
std::string sLocNearestMETAR = RT_METAR_UNKN; ///< location of nearest METAR
long tOff = 0; ///< time offset for which we requested weather
int nErr = 0; ///< How many errors did we have during weather requests?

Expand Down
4 changes: 2 additions & 2 deletions LiveTraffic.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
EXECUTABLE_EXTENSION = xpl;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -844,7 +844,7 @@
DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)";
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
EXECUTABLE_EXTENSION = xpl;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,160 @@
uuid = "C8095CDD-1C39-4D01-99B0-6AD4723390BD"
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "F0D80B1B-7739-4938-A5A5-D288D2CCD55A"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "497"
endingLineNumber = "497"
landmarkName = "RealTrafficConnection::ProcessFetchedData()"
landmarkType = "7">
<Locations>
<Location
uuid = "F0D80B1B-7739-4938-A5A5-D288D2CCD55A - e27fe6228f157cf0"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "RealTrafficConnection::ProcessFetchedData()"
moduleName = "LiveTraffic.xpl"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/birger/Programming/XPlane/LiveTraffic/Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "498"
endingLineNumber = "498">
</Location>
<Location
uuid = "F0D80B1B-7739-4938-A5A5-D288D2CCD55A - e27fe6228f157c91"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "RealTrafficConnection::ProcessFetchedData()"
moduleName = "LiveTraffic.xpl"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/birger/Programming/XPlane/LiveTraffic/Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "497"
endingLineNumber = "497">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "D872D1FD-56B8-49A2-ADB3-C080FB6CB3DC"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "350"
endingLineNumber = "350"
landmarkName = "RealTrafficConnection::ComputeBody(positionTy)"
landmarkType = "7">
<Locations>
<Location
uuid = "D872D1FD-56B8-49A2-ADB3-C080FB6CB3DC - 410b189fbe0007cc"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "RealTrafficConnection::ComputeBody(positionTy const&amp;)"
moduleName = "LiveTraffic.xpl"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/birger/Programming/XPlane/LiveTraffic/Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "350"
endingLineNumber = "350">
</Location>
<Location
uuid = "D872D1FD-56B8-49A2-ADB3-C080FB6CB3DC - 410b189fbe0007cc"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "RealTrafficConnection::ComputeBody(positionTy const&amp;)"
moduleName = "LiveTraffic.xpl"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/birger/Programming/XPlane/LiveTraffic/Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "350"
endingLineNumber = "350">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "B504C1AD-6DEA-40A3-BEE8-34608AA2A1E2"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "356"
endingLineNumber = "356"
landmarkName = "RealTrafficConnection::ComputeBody(positionTy)"
landmarkType = "7">
<Locations>
<Location
uuid = "B504C1AD-6DEA-40A3-BEE8-34608AA2A1E2 - 410b189fbe000696"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "RealTrafficConnection::ComputeBody(positionTy const&amp;)"
moduleName = "LiveTraffic.xpl"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/birger/Programming/XPlane/LiveTraffic/Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "356"
endingLineNumber = "356">
</Location>
<Location
uuid = "B504C1AD-6DEA-40A3-BEE8-34608AA2A1E2 - 410b189fbe000696"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "RealTrafficConnection::ComputeBody(positionTy const&amp;)"
moduleName = "LiveTraffic.xpl"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/birger/Programming/XPlane/LiveTraffic/Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "356"
endingLineNumber = "356">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "0BAD2F32-455E-452B-8BF4-01F6A0138E9D"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Src/LTRealTraffic.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "282"
endingLineNumber = "282"
landmarkName = "RealTrafficConnection::SetRequType(_pos)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
64 changes: 50 additions & 14 deletions Src/LTRealTraffic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,10 @@ std::string RealTrafficConnection::GetStatusText () const
// --- Direct Connection? ---
if (eConnType == RT_CONN_REQU_REPL) {
std::string s =
curr.eRequType == CurrTy::RT_REQU_AUTH ? "Authenticating..." :
curr.eRequType == CurrTy::RT_REQU_WEATHER ? "Fetching weather..." :
curr.eRequType == CurrTy::RT_REQU_AUTH ? "Authenticating..." :
curr.eRequType == CurrTy::RT_REQU_DEAUTH ? "De-authenticating..." :
curr.eRequType == CurrTy::RT_REQU_NEAREST_METAR ? "Fetching weather..." :
curr.eRequType == CurrTy::RT_REQU_WEATHER ? "Fetching weather..." :
LTChannel::GetStatusText();
if (tsAdjust > 1.0) { // historic data?
snprintf(sIntvl, sizeof(sIntvl), MSG_RT_ADJUST,
Expand Down Expand Up @@ -277,19 +279,24 @@ void RealTrafficConnection::SetRequType (const positionTy& _pos)
break;
}

if (!shallRun()) // end the session?
if (!shallRun()) // end the session?
curr.eRequType = CurrTy::RT_REQU_DEAUTH;
else if (curr.sGUID.empty()) // have no GUID? Need authentication
else if (curr.sGUID.empty()) // have no GUID? Need authentication
curr.eRequType = CurrTy::RT_REQU_AUTH;
else if ((std::isnan(rtWx.QNH) || // no Weather, or wrong time offset, or outdated, or moved too far away?
std::labs(curr.tOff - rtWx.tOff) > 120 ||
std::chrono::steady_clock::now() >= rtWx.next ||
rtWx.pos.distRoughSqr(curr.pos) > (RT_DRCT_WX_DIST*RT_DRCT_WX_DIST)))
{
else if (curr.eRequType == CurrTy::RT_REQU_NEAREST_METAR) // previous request was METAR location?
curr.eRequType = CurrTy::RT_REQU_WEATHER;
if (std::labs(curr.tOff - rtWx.tOff) > 120) // if changing the timeoffset (request other historic data) then we must have new weather before proceeding
else if (std::isnan(rtWx.QNH) || // no Weather, or wrong time offset, or outdated, or moved too far away?
std::labs(curr.tOff - rtWx.tOff) > 120 ||
rtWx.pos.distRoughSqr(curr.pos) > (RT_DRCT_WX_DIST*RT_DRCT_WX_DIST))
{
curr.eRequType = CurrTy::RT_REQU_NEAREST_METAR;
if (std::labs(curr.tOff - rtWx.tOff) > 120) // if changing the timeoffset (request other historic data) then we must have new weather before proceeding
rtWx.QNH = NAN;
}
else if (std::chrono::steady_clock::now() >= rtWx.next) // just time for a weather update
{
curr.eRequType = CurrTy::RT_REQU_WEATHER;
}
else
// in all other cases we ask for traffic data
curr.eRequType = CurrTy::RT_REQU_TRAFFIC;
Expand All @@ -313,6 +320,8 @@ std::string RealTrafficConnection::GetURL (const positionTy&)
return RT_AUTH_URL;
case CurrTy::RT_REQU_DEAUTH:
return RT_DEAUTH_URL;
case CurrTy::RT_REQU_NEAREST_METAR:
return RT_NEAREST_METAR_URL;
case CurrTy::RT_REQU_WEATHER:
return RT_WEATHER_URL;
case CurrTy::RT_REQU_TRAFFIC:
Expand All @@ -337,10 +346,17 @@ void RealTrafficConnection::ComputeBody (const positionTy&)
snprintf(s, sizeof(s), RT_DEAUTH_POST,
curr.sGUID.c_str());
break;
case CurrTy::RT_REQU_NEAREST_METAR:
snprintf(s, sizeof(s), RT_NEAREST_METAR_POST,
curr.sGUID.c_str(),
curr.pos.lat(), curr.pos.lon(),
curr.tOff);
break;
case CurrTy::RT_REQU_WEATHER:
snprintf(s, sizeof(s), RT_WEATHER_POST,
curr.sGUID.c_str(),
curr.pos.lat(), curr.pos.lon(), 0L,
rtWx.sLocNearestMETAR.c_str(),
curr.tOff);
break;
case CurrTy::RT_REQU_TRAFFIC:
Expand Down Expand Up @@ -438,12 +454,14 @@ bool RealTrafficConnection::ProcessFetchedData ()

// Wait till next request?
long l = jog_l(pObj, "rrl"); // Wait time till next request
if (!l) l = jog_l(pObj, "wrrl");
switch (curr.eRequType) {
case CurrTy::RT_REQU_AUTH: // after an AUTH request we take the rrl unchanged, ie. as quickly as possible
break;
case CurrTy::RT_REQU_AUTH: // in most cases we continue as quickly as possible
case CurrTy::RT_REQU_DEAUTH:
case CurrTy::RT_REQU_WEATHER: // unfortunately, no `rrl` in weather/deauth responses...
l = 300; // we just continue 300ms later
case CurrTy::RT_REQU_WEATHER:
break;
case CurrTy::RT_REQU_NEAREST_METAR: // after learning the META we continue quickly with the weather request
l = 300;
break;
case CurrTy::RT_REQU_TRAFFIC: // By default we wait at least 8s, or more if RealTraffic instructs us so
if (l < RT_DRCT_DEFAULT_WAIT)
Expand Down Expand Up @@ -473,6 +491,24 @@ bool RealTrafficConnection::ProcessFetchedData ()
return true;
}

// --- Nearest METAR location ---
if (curr.eRequType == CurrTy::RT_REQU_NEAREST_METAR) {
// There shall be two fields: location and distance
rtWx.sLocNearestMETAR = jog_s(pObj, "data.ICAO");
// Set back to default 'UNKN' if too far away, or just nothing returned
const double d = jog_n_nan(pObj, "data.Dist");
if (!std::isnan(d) && d > RT_DRCT_MAX_METAR_DIST_NM) {
LOG_MSG(logDEBUG, "Nearest METAR location too far away, using none");
rtWx.sLocNearestMETAR = RT_METAR_UNKN;
}
// Received nothing?
if (rtWx.sLocNearestMETAR.empty()) {
LOG_MSG(logWARN, "Received no nearest METAR location from RealTraffic");
rtWx.sLocNearestMETAR = RT_METAR_UNKN;
}
return true;
}

// --- Weather ---
if (curr.eRequType == CurrTy::RT_REQU_WEATHER) {
// We are interested in just a single value: local Pressure
Expand Down

0 comments on commit 08981db

Please sign in to comment.