refs #448 Use new METAR source in context and gui

Previously the metar source used to be the FSD connection. Since
all METARs are also available via a webservice, use this source
instead. This allows to retrieve and use METARs even if we are
not connected.
This commit is contained in:
Roland Winklmeier
2015-08-15 22:07:53 +02:00
committed by Mathew Sutcliffe
parent 20ebb07723
commit c5a2136ebd
13 changed files with 114 additions and 69 deletions

View File

@@ -25,6 +25,7 @@ using namespace BlackMisc::Simulation;
using namespace BlackMisc::Network; using namespace BlackMisc::Network;
using namespace BlackMisc::Geo; using namespace BlackMisc::Geo;
using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Weather;
namespace BlackCore namespace BlackCore
{ {
@@ -60,6 +61,7 @@ namespace BlackCore
// AutoConnection: this should also avoid race conditions by updating the bookings // AutoConnection: this should also avoid race conditions by updating the bookings
this->connect(this->m_webDataReader->getBookingReader(), &CVatsimBookingReader::dataRead, this, &CAirspaceMonitor::ps_receivedBookings); this->connect(this->m_webDataReader->getBookingReader(), &CVatsimBookingReader::dataRead, this, &CAirspaceMonitor::ps_receivedBookings);
this->connect(this->m_webDataReader->getDataFileReader(), &CVatsimDataFileReader::dataRead, this, &CAirspaceMonitor::ps_receivedDataFile); this->connect(this->m_webDataReader->getDataFileReader(), &CVatsimDataFileReader::dataRead, this, &CAirspaceMonitor::ps_receivedDataFile);
this->connect(this->m_webDataReader->getMetarReader(), &CVatsimMetarReader::metarUpdated, this, &CAirspaceMonitor::ps_updateMetars);
// Force snapshot in the main event loop // Force snapshot in the main event loop
this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, this, &CAirspaceMonitor::airspaceAircraftSnapshot, Qt::QueuedConnection); this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, this, &CAirspaceMonitor::airspaceAircraftSnapshot, Qt::QueuedConnection);
@@ -322,31 +324,9 @@ namespace BlackCore
return m_otherClients; return m_otherClients;
} }
BlackMisc::Aviation::CInformationMessage CAirspaceMonitor::getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) CMetar CAirspaceMonitor::getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode)
{ {
CInformationMessage metar; return m_metars.findFirstByOrDefault(&CMetar::getAirportIcaoCode, airportIcaoCode);
if (airportIcaoCode.isEmpty()) return metar;
if (this->m_metarCache.contains(airportIcaoCode)) metar = this->m_metarCache[airportIcaoCode];
if (metar.isEmpty() || metar.timeDiffReceivedMs() > 10 * 1000)
{
// outdated, or not in cache at all
this->m_network->sendMetarQuery(airportIcaoCode);
// with this little trick we try to make an asynchronous signal / slot
// based approach a synchronous return value
QTime waitForMetar = QTime::currentTime().addMSecs(1000);
while (QTime::currentTime() < waitForMetar)
{
// process some other events and hope network answer is received already
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
if (m_metarCache.contains(airportIcaoCode))
{
metar = this->m_metarCache[airportIcaoCode];
break;
}
}
}
return metar;
} }
CAtcStation CAirspaceMonitor::getAtcStationForComUnit(const CComSystem &comSystem) CAtcStation CAirspaceMonitor::getAtcStationForComUnit(const CComSystem &comSystem)
@@ -400,7 +380,7 @@ namespace BlackCore
void CAirspaceMonitor::clear() void CAirspaceMonitor::clear()
{ {
m_metarCache.clear(); m_metars.clear();
m_flightPlanCache.clear(); m_flightPlanCache.clear();
m_icaoCodeCache.clear(); m_icaoCodeCache.clear();
@@ -548,21 +528,9 @@ namespace BlackCore
this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm);
} }
void CAirspaceMonitor::ps_metarReceived(const QString &metarMessage) void CAirspaceMonitor::ps_metarReceived(const QString & /** metarMessage **/)
{ {
if (!this->m_connected || metarMessage.length() < 10) return; // invalid // deprecated
const QString icaoCode = metarMessage.left(4).toUpper();
const QString icaoCodeTower = icaoCode + "_TWR";
CCallsign callsignTower(icaoCodeTower);
CInformationMessage metar(CInformationMessage::METAR, metarMessage);
// add METAR to existing stations
CPropertyIndexVariantMap vm(CAtcStation::IndexMetar, CVariant::from(metar));
this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsignTower, vm);
this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsignTower, vm);
this->m_metarCache.insert(icaoCode, metar);
if (this->m_atcStationsOnline.containsCallsign(callsignTower)) { emit this->changedAtcStationsOnline(); }
if (this->m_atcStationsBooked.containsCallsign(callsignTower)) { emit this->changedAtcStationsBooked(); }
} }
void CAirspaceMonitor::ps_flightPlanReceived(const CCallsign &callsign, const CFlightPlan &flightPlan) void CAirspaceMonitor::ps_flightPlanReceived(const CCallsign &callsign, const CFlightPlan &flightPlan)
@@ -647,6 +615,12 @@ namespace BlackCore
} }
} }
void CAirspaceMonitor::ps_updateMetars(const CMetarSet &metars)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
m_metars = metars;
}
void CAirspaceMonitor::ps_sendReadyForModelMatching(const CCallsign &callsign, int trial) void CAirspaceMonitor::ps_sendReadyForModelMatching(const CCallsign &callsign, int trial)
{ {
// some checks for special conditions, e.g. logout -> empty list, but still signals pending // some checks for special conditions, e.g. logout -> empty list, but still signals pending

View File

@@ -14,12 +14,14 @@
#include "blackcore/blackcoreexport.h" #include "blackcore/blackcoreexport.h"
#include "blackcore/network.h" #include "blackcore/network.h"
#include "blackcore/vatsim_metar_reader.h"
#include "airspace_analyzer.h" #include "airspace_analyzer.h"
#include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/simulation/simulatedaircraftlist.h"
#include "blackmisc/simulation/ownaircraftprovider.h" #include "blackmisc/simulation/ownaircraftprovider.h"
#include "blackmisc/simulation/remoteaircraftprovider.h" #include "blackmisc/simulation/remoteaircraftprovider.h"
#include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/atcstationlist.h"
#include "blackmisc/aviation/aircraftsituationlist.h" #include "blackmisc/aviation/aircraftsituationlist.h"
#include "blackmisc/weather/metarset.h"
#include "blackmisc/network/clientlist.h" #include "blackmisc/network/clientlist.h"
#include "blackmisc/aviation/flightplan.h" #include "blackmisc/aviation/flightplan.h"
#include "blackmisc/network/userlist.h" #include "blackmisc/network/userlist.h"
@@ -116,7 +118,7 @@ namespace BlackCore
BlackMisc::Network::CClientList getOtherClientsForCallsigns(const BlackMisc::Aviation::CCallsignSet &callsigns) const; BlackMisc::Network::CClientList getOtherClientsForCallsigns(const BlackMisc::Aviation::CCallsignSet &callsigns) const;
//! Returns a METAR for the given airport, if available //! Returns a METAR for the given airport, if available
BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode); BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode);
//! Returns the current online ATC stations //! Returns the current online ATC stations
BlackMisc::Aviation::CAtcStationList getAtcStationsOnline() const { return m_atcStationsOnline; } BlackMisc::Aviation::CAtcStationList getAtcStationsOnline() const { return m_atcStationsOnline; }
@@ -205,13 +207,13 @@ namespace BlackCore
BlackMisc::Aviation::CAtcStationList m_atcStationsBooked; BlackMisc::Aviation::CAtcStationList m_atcStationsBooked;
BlackMisc::Network::CClientList m_otherClients; BlackMisc::Network::CClientList m_otherClients;
BlackMisc::Simulation::CSimulatedAircraftList m_aircraftInRange; BlackMisc::Simulation::CSimulatedAircraftList m_aircraftInRange;
BlackMisc::Weather::CMetarSet m_metars;
// hashs, because not sorted by key but keeping order // hashs, because not sorted by key but keeping order
CSituationsPerCallsign m_situationsByCallsign; //!< situations, for performance reasons per callsign CSituationsPerCallsign m_situationsByCallsign; //!< situations, for performance reasons per callsign
CPartsPerCallsign m_partsByCallsign; //!< parts, for performance reasons per callsign CPartsPerCallsign m_partsByCallsign; //!< parts, for performance reasons per callsign
BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts
QMap<BlackMisc::Aviation::CAirportIcaoCode, BlackMisc::Aviation::CInformationMessage> m_metarCache;
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CFlightPlan> m_flightPlanCache; QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CFlightPlan> m_flightPlanCache;
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftIcaoData> m_icaoCodeCache; QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftIcaoData> m_icaoCodeCache;
@@ -277,6 +279,7 @@ namespace BlackCore
void ps_frequencyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency); void ps_frequencyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency);
void ps_receivedBookings(const BlackMisc::Aviation::CAtcStationList &bookedStations); void ps_receivedBookings(const BlackMisc::Aviation::CAtcStationList &bookedStations);
void ps_receivedDataFile(); void ps_receivedDataFile();
void ps_updateMetars(const BlackMisc::Weather::CMetarSet &metars);
void ps_aircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, bool isFull); void ps_aircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, bool isFull);
void ps_aircraftInterimUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation); void ps_aircraftInterimUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation);
void ps_sendInterimPositions(); void ps_sendInterimPositions();

View File

@@ -16,6 +16,7 @@
#include "blackcore/context.h" #include "blackcore/context.h"
#include "blackmisc/identifier.h" #include "blackmisc/identifier.h"
#include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/atcstationlist.h"
#include "blackmisc/weather/metar.h"
#include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/simulation/simulatedaircraftlist.h"
#include "blackmisc/statusmessage.h" #include "blackmisc/statusmessage.h"
#include "blackmisc/statusmessagelist.h" #include "blackmisc/statusmessagelist.h"
@@ -140,6 +141,9 @@ namespace BlackCore
//! Bookings read //! Bookings read
void vatsimBookingsRead(int number); void vatsimBookingsRead(int number);
//! Metar read
void vatsimMetarsRead(int number);
//! ICAO codes read //! ICAO codes read
void aircraftIcaoCodeRead(int number); void aircraftIcaoCodeRead(int number);
@@ -238,7 +242,7 @@ namespace BlackCore
virtual bool parseCommandLine(const QString &commandLine, const BlackMisc::CIdentifier &originator) = 0; virtual bool parseCommandLine(const QString &commandLine, const BlackMisc::CIdentifier &originator) = 0;
//! Get METAR, if not available request it (code such as EDDF, KLAX) //! Get METAR, if not available request it (code such as EDDF, KLAX)
virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) = 0; virtual BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) = 0;
//! Use the selected COM1/2 frequencies, and get the corresponding voice room for it //! Use the selected COM1/2 frequencies, and get the corresponding voice room for it
virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const = 0; virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const = 0;

View File

@@ -134,11 +134,11 @@ namespace BlackCore
} }
//! \copydoc IContextNetwork::getMetar //! \copydoc IContextNetwork::getMetar
virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override
{ {
Q_UNUSED(airportIcaoCode); Q_UNUSED(airportIcaoCode);
logEmptyContextWarning(Q_FUNC_INFO); logEmptyContextWarning(Q_FUNC_INFO);
return BlackMisc::Aviation::CInformationMessage(); return {};
} }
//! \copydoc IContextNetwork::getSelectedVoiceRooms() //! \copydoc IContextNetwork::getSelectedVoiceRooms()

View File

@@ -14,6 +14,7 @@
#include "context_simulator.h" #include "context_simulator.h"
#include "context_ownaircraft_impl.h" #include "context_ownaircraft_impl.h"
#include "network_vatlib.h" #include "network_vatlib.h"
#include "vatsim_metar_reader.h"
#include "airspace_monitor.h" #include "airspace_monitor.h"
#include "web_datareader.h" #include "web_datareader.h"
#include "blackmisc/networkutils.h" #include "blackmisc/networkutils.h"
@@ -32,6 +33,7 @@ using namespace BlackMisc::Network;
using namespace BlackMisc::Geo; using namespace BlackMisc::Geo;
using namespace BlackMisc::Audio; using namespace BlackMisc::Audio;
using namespace BlackMisc::Simulation; using namespace BlackMisc::Simulation;
using namespace BlackMisc::Weather;
namespace BlackCore namespace BlackCore
{ {
@@ -59,7 +61,8 @@ namespace BlackCore
this->m_webDataReader = new CWebDataReader(CWebDataReader::AllReaders, this); this->m_webDataReader = new CWebDataReader(CWebDataReader::AllReaders, this);
this->m_webReaderSignalConnections = this->m_webDataReader->connectVatsimDataSignals( this->m_webReaderSignalConnections = this->m_webDataReader->connectVatsimDataSignals(
std::bind(&CContextNetwork::vatsimBookingsRead, this, std::placeholders::_1), std::bind(&CContextNetwork::vatsimBookingsRead, this, std::placeholders::_1),
std::bind(&CContextNetwork::vatsimDataFileRead, this, std::placeholders::_1)); std::bind(&CContextNetwork::vatsimDataFileRead, this, std::placeholders::_1),
std::bind(&CContextNetwork::vatsimMetarsRead, this, std::placeholders::_1));
this->m_webReaderSignalConnections.append( this->m_webReaderSignalConnections.append(
this->m_webDataReader->connectSwiftDatabaseSignals( this->m_webDataReader->connectSwiftDatabaseSignals(
this, // the object here must be the same as in the bind this, // the object here must be the same as in the bind
@@ -441,6 +444,12 @@ namespace BlackCore
m_airspace->analyzer()->setSimulatorRenderRestrictionsChanged(restricted, enabled, maxAircraft, maxRenderedDistance, maxRenderedBoundary); m_airspace->analyzer()->setSimulatorRenderRestrictionsChanged(restricted, enabled, maxAircraft, maxRenderedDistance, maxRenderedBoundary);
} }
void CContextNetwork::ps_updateMetars(const BlackMisc::Weather::CMetarSet &metars)
{
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
CLogMessage(this).info("%1 METARs updated") << metars.size();
}
void CContextNetwork::ps_checkForSupervisiorTextMessage(const CTextMessageList &messages) void CContextNetwork::ps_checkForSupervisiorTextMessage(const CTextMessageList &messages)
{ {
if (messages.containsPrivateMessages()) if (messages.containsPrivateMessages())
@@ -617,7 +626,7 @@ namespace BlackCore
this->m_airspace->testAddAircraftParts(parts, incremental); this->m_airspace->testAddAircraftParts(parts, incremental);
} }
BlackMisc::Aviation::CInformationMessage CContextNetwork::getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) CMetar CContextNetwork::getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode)
{ {
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << airportIcaoCode; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << airportIcaoCode; }
return m_airspace->getMetar(airportIcaoCode); return m_airspace->getMetar(airportIcaoCode);

View File

@@ -21,6 +21,7 @@
#include "blackmisc/simulation/remoteaircraftprovider.h" #include "blackmisc/simulation/remoteaircraftprovider.h"
#include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/atcstationlist.h"
#include "blackmisc/aviation/aircraftsituationlist.h" #include "blackmisc/aviation/aircraftsituationlist.h"
#include "blackmisc/weather/metarset.h"
#include "blackmisc/setnetwork.h" #include "blackmisc/setnetwork.h"
#include "blackmisc/network/clientlist.h" #include "blackmisc/network/clientlist.h"
#include "blackmisc/digestsignal.h" #include "blackmisc/digestsignal.h"
@@ -33,6 +34,7 @@ namespace BlackCore
{ {
class CAirspaceMonitor; class CAirspaceMonitor;
class CWebDataReader; class CWebDataReader;
class CVatsimMetarReader;
//! Network context implementation //! Network context implementation
class BLACKCORE_EXPORT CContextNetwork : class BLACKCORE_EXPORT CContextNetwork :
@@ -168,7 +170,7 @@ namespace BlackCore
virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const override; virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const override;
//! \copydoc IContextNetwork::getMetar //! \copydoc IContextNetwork::getMetar
virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override; BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override;
//! \copydoc IContextNetwork::getSelectedVoiceRooms() //! \copydoc IContextNetwork::getSelectedVoiceRooms()
virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const override; virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const override;
@@ -244,10 +246,14 @@ namespace BlackCore
BlackMisc::CDigestSignal m_dsAtcStationsOnlineChanged { this, &IContextNetwork::changedAtcStationsOnline, &IContextNetwork::changedAtcStationsOnlineDigest, 750, 4 }; BlackMisc::CDigestSignal m_dsAtcStationsOnlineChanged { this, &IContextNetwork::changedAtcStationsOnline, &IContextNetwork::changedAtcStationsOnlineDigest, 750, 4 };
BlackMisc::CDigestSignal m_dsAircraftsInRangeChanged { this, &IContextNetwork::changedAircraftInRange, &IContextNetwork::changedAircraftInRangeDigest, 750, 4 }; BlackMisc::CDigestSignal m_dsAircraftsInRangeChanged { this, &IContextNetwork::changedAircraftInRange, &IContextNetwork::changedAircraftInRangeDigest, 750, 4 };
//! Own aircraft from \sa CContextOwnAircraft //! Own aircraft from \sa CContextOwnAircraft
const BlackMisc::Simulation::CSimulatedAircraft ownAircraft() const; const BlackMisc::Simulation::CSimulatedAircraft ownAircraft() const;
private slots: private slots:
//! Update METAR collection
void ps_updateMetars(const BlackMisc::Weather::CMetarSet &metars);
//! Check if a supervisor message was received //! Check if a supervisor message was received
void ps_checkForSupervisiorTextMessage(const BlackMisc::Network::CTextMessageList &messages); void ps_checkForSupervisiorTextMessage(const BlackMisc::Network::CTextMessageList &messages);

View File

@@ -16,6 +16,7 @@
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Network; using namespace BlackMisc::Network;
using namespace BlackMisc::Aviation; using namespace BlackMisc::Aviation;
using namespace BlackMisc::Weather;
namespace BlackCore namespace BlackCore
{ {
@@ -75,6 +76,9 @@ namespace BlackCore
s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(),
"vatsimBookingsRead", this, SIGNAL(vatsimBookingsRead(int))); "vatsimBookingsRead", this, SIGNAL(vatsimBookingsRead(int)));
Q_ASSERT(s); Q_ASSERT(s);
s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(),
"vatsimMetarsRead", this, SIGNAL(vatsimMetarsRead(int)));
Q_ASSERT(s);
s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(),
"changedRemoteAircraftModel", this, SIGNAL(changedRemoteAircraftModel(BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::CIdentifier))); "changedRemoteAircraftModel", this, SIGNAL(changedRemoteAircraftModel(BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::CIdentifier)));
Q_ASSERT(s); Q_ASSERT(s);
@@ -268,9 +272,9 @@ namespace BlackCore
return this->m_dBusInterface->callDBusRet<BlackMisc::Aviation::CFlightPlan>(QLatin1Literal("loadFlightPlanFromNetwork"), callsign); return this->m_dBusInterface->callDBusRet<BlackMisc::Aviation::CFlightPlan>(QLatin1Literal("loadFlightPlanFromNetwork"), callsign);
} }
CInformationMessage CContextNetworkProxy::getMetar(const CAirportIcaoCode &airportIcaoCode) CMetar CContextNetworkProxy::getMetar(const CAirportIcaoCode &airportIcaoCode)
{ {
return this->m_dBusInterface->callDBusRet<BlackMisc::Aviation::CInformationMessage>(QLatin1Literal("getMetar"), airportIcaoCode); return this->m_dBusInterface->callDBusRet<BlackMisc::Weather::CMetar>(QLatin1Literal("getMetar"), airportIcaoCode);
} }
} // namespace } // namespace

View File

@@ -100,7 +100,7 @@ namespace BlackCore
virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const override; virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const override;
//! \copydoc IContextNetwork::getMetar //! \copydoc IContextNetwork::getMetar
virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override; BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override;
//! \copydoc IContextNetwork::getSelectedVoiceRooms() //! \copydoc IContextNetwork::getSelectedVoiceRooms()
virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const override; virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const override;

View File

@@ -15,7 +15,8 @@ namespace BlackCore
m_protocolIcaoReader("http"), m_serverIcaoReader("ubuntu12"), m_baseUrlIcaoReader("vatrep/public"), m_protocolIcaoReader("http"), m_serverIcaoReader("ubuntu12"), m_baseUrlIcaoReader("vatrep/public"),
m_protocolModelReader("http"), m_serverModelReader("ubuntu12"), m_baseUrlModelReader("vatrep/public"), m_protocolModelReader("http"), m_serverModelReader("ubuntu12"), m_baseUrlModelReader("vatrep/public"),
m_bookingsUrl("http://vatbook.euroutepro.com/xml2.php"), m_bookingsUrl("http://vatbook.euroutepro.com/xml2.php"),
m_vatsimDataFileUrls({ "http://info.vroute.net/vatsim-data.txt" }) m_vatsimDataFileUrls({ "http://info.vroute.net/vatsim-data.txt" }),
m_metarUrl("http://metar.vatsim.net/metar.php?id=all")
{ } { }
const CGlobalReaderSettings &CGlobalReaderSettings::instance() const CGlobalReaderSettings &CGlobalReaderSettings::instance()

View File

@@ -46,6 +46,9 @@ namespace BlackCore
//! VATSIM data file URLs //! VATSIM data file URLs
const QStringList &vatsimDataFileUrls() const { return m_vatsimDataFileUrls; } const QStringList &vatsimDataFileUrls() const { return m_vatsimDataFileUrls; }
//! VATSIM metar url
const QString &vatsimMetarUrl() const { return m_metarUrl; }
//! Singleton //! Singleton
static const CGlobalReaderSettings &instance(); static const CGlobalReaderSettings &instance();
@@ -64,6 +67,7 @@ namespace BlackCore
QString m_baseUrlModelReader; QString m_baseUrlModelReader;
QString m_bookingsUrl; QString m_bookingsUrl;
QStringList m_vatsimDataFileUrls; QStringList m_vatsimDataFileUrls;
QString m_metarUrl;
}; };
} }
#endif // guard #endif // guard

View File

@@ -10,6 +10,7 @@
#include "blackcore/web_datareader.h" #include "blackcore/web_datareader.h"
#include "vatsimbookingreader.h" #include "vatsimbookingreader.h"
#include "vatsimdatafilereader.h" #include "vatsimdatafilereader.h"
#include "vatsim_metar_reader.h"
#include "icaodatareader.h" #include "icaodatareader.h"
#include "modeldatareader.h" #include "modeldatareader.h"
#include "global_reader_settings.h" #include "global_reader_settings.h"
@@ -32,7 +33,9 @@ namespace BlackCore
this->initReaders(readerFlags); this->initReaders(readerFlags);
} }
QList<QMetaObject::Connection> CWebDataReader::connectVatsimDataSignals(std::function<void(int)> bookingsRead, std::function<void(int)> dataFileRead) QList<QMetaObject::Connection> CWebDataReader::connectVatsimDataSignals(std::function<void(int)> bookingsRead,
std::function<void(int)> dataFileRead,
std::function<void(int)> metarRead)
{ {
// bind does not allow to define connection type // bind does not allow to define connection type
// so anything in its own thread will be sent with this thread affinity // so anything in its own thread will be sent with this thread affinity
@@ -51,6 +54,13 @@ namespace BlackCore
Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed"); Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed");
cl.append(c2); cl.append(c2);
} }
if (m_readerFlags.testFlag(VatsimMetarReader))
{
QMetaObject::Connection c3 = connect(this, &CWebDataReader::vatsimMetarRead, metarRead);
Q_ASSERT_X(c3, Q_FUNC_INFO, "connect failed");
cl.append(c3);
}
return cl; return cl;
} }
@@ -138,6 +148,7 @@ namespace BlackCore
this->disconnect(); // all signals this->disconnect(); // all signals
if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); } if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); }
if (this->m_vatsimDataFileReader) { this->m_vatsimDataFileReader->requestStop(); this->m_vatsimDataFileReader->quit(); } if (this->m_vatsimDataFileReader) { this->m_vatsimDataFileReader->requestStop(); this->m_vatsimDataFileReader->quit(); }
if (this->m_vatsimMetarReader) { this->m_vatsimMetarReader->requestStop(); this->m_vatsimMetarReader->quit(); }
} }
const CLogCategoryList &CWebDataReader::getLogCategories() const CLogCategoryList &CWebDataReader::getLogCategories()
@@ -166,7 +177,16 @@ namespace BlackCore
this->m_vatsimDataFileReader->setInterval(90 * 1000); this->m_vatsimDataFileReader->setInterval(90 * 1000);
} }
// 3. ICAO data reader // 3. VATSIM metar
if (flags.testFlag(VatsimMetarReader))
{
this->m_vatsimMetarReader = new CVatsimMetarReader(this, CGlobalReaderSettings::instance().vatsimMetarUrl());
connect(this->m_vatsimMetarReader, &CVatsimMetarReader::metarUpdated, this, &CWebDataReader::ps_metarRead);
this->m_vatsimMetarReader->start();
this->m_vatsimMetarReader->setInterval(5 * 60 * 1000);
}
// 4. ICAO data reader
if (flags.testFlag(IcaoDataReader)) if (flags.testFlag(IcaoDataReader))
{ {
this->m_icaoDataReader = new CIcaoDataReader(this, CGlobalReaderSettings::instance().protocolIcaoReader(), CGlobalReaderSettings::instance().serverIcaoReader(), CGlobalReaderSettings::instance().baseUrlIcaoReader()); this->m_icaoDataReader = new CIcaoDataReader(this, CGlobalReaderSettings::instance().protocolIcaoReader(), CGlobalReaderSettings::instance().serverIcaoReader(), CGlobalReaderSettings::instance().baseUrlIcaoReader());
@@ -175,7 +195,7 @@ namespace BlackCore
this->m_icaoDataReader->start(); this->m_icaoDataReader->start();
} }
// 4. Model reader // 5. Model reader
if (flags.testFlag(ModelReader)) if (flags.testFlag(ModelReader))
{ {
this->m_modelDataReader = new CModelDataReader(this, CGlobalReaderSettings::instance().protocolModelReader(), CGlobalReaderSettings::instance().serverModelReader(), CGlobalReaderSettings::instance().baseUrlModelReader()); this->m_modelDataReader = new CModelDataReader(this, CGlobalReaderSettings::instance().protocolModelReader(), CGlobalReaderSettings::instance().serverModelReader(), CGlobalReaderSettings::instance().baseUrlModelReader());
@@ -198,6 +218,12 @@ namespace BlackCore
emit vatsimDataFileRead(lines); emit vatsimDataFileRead(lines);
} }
void CWebDataReader::ps_metarRead(const BlackMisc::Weather::CMetarSet &metars)
{
CLogMessage(this).info("Read %1 VATSIM metar stations") << metars.size();
emit vatsimMetarRead(metars.size());
}
void CWebDataReader::ps_readAircraftIcaoCodes(int number) void CWebDataReader::ps_readAircraftIcaoCodes(int number)
{ {
CLogMessage(this).info("Read %1 aircraft ICAO codes") << number; CLogMessage(this).info("Read %1 aircraft ICAO codes") << number;
@@ -241,6 +267,7 @@ namespace BlackCore
if (this->m_vatsimBookingReader) {this->m_vatsimBookingReader->readInBackgroundThread(); } if (this->m_vatsimBookingReader) {this->m_vatsimBookingReader->readInBackgroundThread(); }
if (this->m_vatsimDataFileReader) this->m_vatsimDataFileReader->readInBackgroundThread(); if (this->m_vatsimDataFileReader) this->m_vatsimDataFileReader->readInBackgroundThread();
if (this->m_vatsimMetarReader) this->m_vatsimMetarReader->readInBackgroundThread();
if (this->m_icaoDataReader) { this->m_icaoDataReader->readInBackgroundThread(); } if (this->m_icaoDataReader) { this->m_icaoDataReader->readInBackgroundThread(); }
if (this->m_modelDataReader) { this->m_modelDataReader->readInBackgroundThread(); } if (this->m_modelDataReader) { this->m_modelDataReader->readInBackgroundThread(); }
} }

View File

@@ -20,6 +20,7 @@
#include "blackmisc/aviation/aircrafticaocodelist.h" #include "blackmisc/aviation/aircrafticaocodelist.h"
#include "blackmisc/network/serverlist.h" #include "blackmisc/network/serverlist.h"
#include "blackmisc/simulation/distributorlist.h" #include "blackmisc/simulation/distributorlist.h"
#include "blackmisc/weather/metarset.h"
#include <QObject> #include <QObject>
namespace BlackCore namespace BlackCore
@@ -28,6 +29,7 @@ namespace BlackCore
class CVatsimDataFileReader; class CVatsimDataFileReader;
class CIcaoDataReader; class CIcaoDataReader;
class CModelDataReader; class CModelDataReader;
class CVatsimMetarReader;
/** /**
* Encapsulates reading data from web sources * Encapsulates reading data from web sources
@@ -43,9 +45,10 @@ namespace BlackCore
None = 0, None = 0,
VatsimBookingReader = 1 << 0, VatsimBookingReader = 1 << 0,
VatsimDataReader = 1 << 1, VatsimDataReader = 1 << 1,
IcaoDataReader = 1 << 2, VatsimMetarReader = 1 << 2,
ModelReader = 1 << 3, IcaoDataReader = 1 << 3,
AllVatsimReaders = VatsimBookingReader | VatsimDataReader, ModelReader = 1 << 4,
AllVatsimReaders = VatsimBookingReader | VatsimDataReader | VatsimMetarReader,
AllSwiftDbReaders = IcaoDataReader | ModelReader, AllSwiftDbReaders = IcaoDataReader | ModelReader,
AllReaders = 0xFFFF AllReaders = 0xFFFF
}; };
@@ -58,7 +61,9 @@ namespace BlackCore
void gracefulShutdown(); void gracefulShutdown();
//! Relay signals for VATSIM data //! Relay signals for VATSIM data
QList<QMetaObject::Connection> connectVatsimDataSignals(std::function<void(int)> bookingsRead, std::function<void(int)> dataFileRead); QList<QMetaObject::Connection> connectVatsimDataSignals(std::function<void(int)> bookingsRead,
std::function<void(int)> dataFileRead,
std::function<void(int)> metarRead);
//! Relay signals for swift data //! Relay signals for swift data
QList<QMetaObject::Connection> connectSwiftDatabaseSignals( QList<QMetaObject::Connection> connectSwiftDatabaseSignals(
@@ -100,6 +105,9 @@ namespace BlackCore
//! Data file reader //! Data file reader
CVatsimDataFileReader *getDataFileReader() const { return m_vatsimDataFileReader; } CVatsimDataFileReader *getDataFileReader() const { return m_vatsimDataFileReader; }
//! Metar reader
CVatsimMetarReader *getMetarReader() const { return m_vatsimMetarReader; }
//! Reader flags //! Reader flags
WebReader getReaderFlags() const { return m_readerFlags; } WebReader getReaderFlags() const { return m_readerFlags; }
@@ -117,6 +125,9 @@ namespace BlackCore
//! Bookings read //! Bookings read
void vatsimBookingsRead(int number); void vatsimBookingsRead(int number);
//! Metars read
void vatsimMetarRead(int number);
//! ICAO codes read //! ICAO codes read
void aircraftIcaoCodeRead(int number); void aircraftIcaoCodeRead(int number);
@@ -139,6 +150,9 @@ namespace BlackCore
//! Data file has been read //! Data file has been read
void ps_dataFileRead(int lines); void ps_dataFileRead(int lines);
//! Metars have been read
void ps_metarRead(const BlackMisc::Weather::CMetarSet &metars);
//! Read ICAO codes //! Read ICAO codes
void ps_readAircraftIcaoCodes(int number); void ps_readAircraftIcaoCodes(int number);
@@ -163,6 +177,7 @@ namespace BlackCore
// for reading XML and VATSIM data files // for reading XML and VATSIM data files
CVatsimBookingReader *m_vatsimBookingReader = nullptr; CVatsimBookingReader *m_vatsimBookingReader = nullptr;
CVatsimDataFileReader *m_vatsimDataFileReader = nullptr; CVatsimDataFileReader *m_vatsimDataFileReader = nullptr;
CVatsimMetarReader *m_vatsimMetarReader = nullptr;
CIcaoDataReader *m_icaoDataReader = nullptr; CIcaoDataReader *m_icaoDataReader = nullptr;
CModelDataReader *m_modelDataReader = nullptr; CModelDataReader *m_modelDataReader = nullptr;
}; };

View File

@@ -12,6 +12,7 @@
#include "ui_atcstationcomponent.h" #include "ui_atcstationcomponent.h"
#include "blackmisc/aviation/informationmessage.h" #include "blackmisc/aviation/informationmessage.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/weather/metar.h"
#include "blackcore/context_network.h" #include "blackcore/context_network.h"
#include "blackcore/context_ownaircraft.h" #include "blackcore/context_ownaircraft.h"
@@ -21,6 +22,7 @@ using namespace BlackGui::Views;
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Aviation; using namespace BlackMisc::Aviation;
using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Weather;
using namespace BlackCore; using namespace BlackCore;
namespace BlackGui namespace BlackGui
@@ -135,7 +137,6 @@ namespace BlackGui
{ {
this->ui->tvp_AtcStationsOnline->clear(); this->ui->tvp_AtcStationsOnline->clear();
this->updateTreeView(); this->updateTreeView();
this->ui->le_AtcStationsOnlineMetar->clear();
} }
} }
@@ -146,24 +147,22 @@ namespace BlackGui
void CAtcStationComponent::getMetar(const QString &airportIcaoCode) void CAtcStationComponent::getMetar(const QString &airportIcaoCode)
{ {
if (!this->getIContextNetwork()->isConnected())
{
this->ui->te_AtcStationsOnlineInfo->clear();
return;
}
QString icao = airportIcaoCode.isEmpty() ? this->ui->le_AtcStationsOnlineMetar->text().trimmed().toUpper() : airportIcaoCode.trimmed().toUpper(); QString icao = airportIcaoCode.isEmpty() ? this->ui->le_AtcStationsOnlineMetar->text().trimmed().toUpper() : airportIcaoCode.trimmed().toUpper();
this->ui->le_AtcStationsOnlineMetar->setText(icao); this->ui->le_AtcStationsOnlineMetar->setText(icao);
if (icao.length() != 4) { return; } if (icao.length() != 4) { return; }
CInformationMessage metar = this->getIContextNetwork()->getMetar(icao); CMetar metar = this->getIContextNetwork()->getMetar(icao);
if (metar.getType() != CInformationMessage::METAR) { return; } if (metar == CMetar())
if (metar.isEmpty())
{ {
this->ui->te_AtcStationsOnlineInfo->clear(); this->ui->te_AtcStationsOnlineInfo->clear();
} }
else else
{ {
this->ui->te_AtcStationsOnlineInfo->setText(metar.getMessage()); QString metarText = metar.getMessage();
metarText += "\n\n";
metarText += metar.getMetarText();
this->ui->te_AtcStationsOnlineInfo->setText(metarText);
} }
this->ui->le_AtcStationsOnlineMetar->clear();
} }
void CAtcStationComponent::ps_reloadAtcStationsBooked() void CAtcStationComponent::ps_reloadAtcStationsBooked()
@@ -210,7 +209,6 @@ namespace BlackGui
{ {
this->ui->tvp_AtcStationsOnline->clear(); this->ui->tvp_AtcStationsOnline->clear();
this->updateTreeView(); this->updateTreeView();
this->ui->le_AtcStationsOnlineMetar->clear();
} }
} }