]> git.mxchange.org Git - flightgear.git/blobdiff - src/Environment/realwx_ctrl.cxx
Fix max-metar-age, bug #1076.
[flightgear.git] / src / Environment / realwx_ctrl.cxx
index 6be99082e6fa942bb03933a7545df663be8ed514..056a0bb6a8d38d6169ef2cf12679861b192e7ce2 100644 (file)
@@ -63,12 +63,13 @@ public:
 
 class LiveMetarProperties : public MetarProperties, MetarDataHandler {
 public:
-    LiveMetarProperties( SGPropertyNode_ptr rootNode, MetarRequester * metarRequester );
+    LiveMetarProperties( SGPropertyNode_ptr rootNode, MetarRequester * metarRequester, int maxAge );
     virtual ~LiveMetarProperties();
     virtual void update( double dt );
 
     virtual double getTimeToLive() const { return _timeToLive; }
-    virtual void setTimeToLive( double value ) { _timeToLive = value; }
+    virtual void resetTimeToLive()
+    { _timeToLive = 0.00; _pollingTimer = 0.0; }
 
     // implementation of MetarDataHandler
     virtual void handleMetarData( const std::string & data );
@@ -80,15 +81,17 @@ private:
     double _timeToLive;
     double _pollingTimer;
     MetarRequester * _metarRequester;
+    int _maxAge;
 };
 
 typedef SGSharedPtr<LiveMetarProperties> LiveMetarProperties_ptr;
 
-LiveMetarProperties::LiveMetarProperties( SGPropertyNode_ptr rootNode, MetarRequester * metarRequester ) :
+LiveMetarProperties::LiveMetarProperties( SGPropertyNode_ptr rootNode, MetarRequester * metarRequester, int maxAge ) :
     MetarProperties( rootNode ),
     _timeToLive(0.0),
     _pollingTimer(0.0),
-    _metarRequester(metarRequester)
+    _metarRequester(metarRequester),
+    _maxAge(maxAge)
 {
     _tiedProperties.Tie("time-to-live", &_timeToLive );
 }
@@ -102,7 +105,7 @@ void LiveMetarProperties::update( double dt )
 {
     _timeToLive -= dt;
     _pollingTimer -= dt;
-    if( _timeToLive < 0.0 ) {
+    if( _timeToLive <= 0.0 ) {
         _timeToLive = 0.0;
         std::string stationId = getStationId();
         if( stationId.empty() ) return;
@@ -114,9 +117,25 @@ void LiveMetarProperties::update( double dt )
 
 void LiveMetarProperties::handleMetarData( const std::string & data )
 {
-    SG_LOG( SG_ENVIRONMENT, SG_INFO, "LiveMetarProperties::handleMetarData() received METAR for " << getStationId() << ": " << data );
+    SG_LOG( SG_ENVIRONMENT, SG_DEBUG, "LiveMetarProperties::handleMetarData() received METAR for " << getStationId() << ": " << data );
     _timeToLive = DEFAULT_TIME_TO_LIVE_SECONDS;
-    setMetar( data );
+    
+    SGSharedPtr<FGMetar> m;
+    try {
+        m = new FGMetar(data.c_str());
+    }
+    catch( sg_io_exception ) {
+        SG_LOG( SG_ENVIRONMENT, SG_WARN, "Can't parse metar: " << data );
+        return;
+    }
+
+    if (_maxAge && (m->getAge_min() > _maxAge)) {
+        // METAR is older than max-age, ignore
+        SG_LOG( SG_ENVIRONMENT, SG_DEBUG, "Ignoring outdated METAR for " << getStationId());
+        return;
+    }
+    
+    setMetar( m );
 }
 
 /* -------------------------------------------------------------------------------- */
@@ -215,7 +234,9 @@ BasicRealWxController::BasicRealWxController( SGPropertyNode_ptr rootNode, Metar
 {
     // at least instantiate MetarProperties for /environment/metar
     _metarProperties.push_back( new LiveMetarProperties( 
-            fgGetNode( rootNode->getStringValue("metar", "/environment/metar"), true ), metarRequester ));
+            fgGetNode( rootNode->getStringValue("metar", "/environment/metar"), true ),
+            metarRequester,
+            getMetarMaxAgeMin()));
 
     BOOST_FOREACH( SGPropertyNode_ptr n, rootNode->getChildren("metar") ) {
         SGPropertyNode_ptr metarNode = fgGetNode( n->getStringValue(), true );
@@ -234,6 +255,8 @@ BasicRealWxController::~BasicRealWxController()
 void BasicRealWxController::init()
 {
     _wasEnabled = false;
+    
+    checkNearbyMetar();
     update(0); // fetch data ASAP
     
     globals->get_event_mgr()->addTask("checkNearbyMetar", this,
@@ -243,6 +266,8 @@ void BasicRealWxController::init()
 void BasicRealWxController::reinit()
 {
     _wasEnabled = false;
+    checkNearbyMetar();
+    update(0); // fetch data ASAP
 }
     
 void BasicRealWxController::shutdown()
@@ -262,14 +287,13 @@ void BasicRealWxController::unbind()
 }
 
 void BasicRealWxController::update( double dt )
-{
+{  
   if( _enabled ) {
     bool firstIteration = !_wasEnabled;
-
     // clock tick for every METAR in stock
     BOOST_FOREACH(LiveMetarProperties* p, _metarProperties) {
       // first round? All received METARs are outdated
-      if( firstIteration ) p->setTimeToLive( 0.0 );
+      if( firstIteration ) p->resetTimeToLive();
       p->update(dt);
     }
 
@@ -287,7 +311,7 @@ void BasicRealWxController::addMetarAtPath(const string& propPath, const string&
       // already exists
       if (p->getStationId() != icao) {
         p->setStationId(icao);
-        p->setTimeToLive(0.0);
+        p->resetTimeToLive();
       }
       
       return;
@@ -296,7 +320,7 @@ void BasicRealWxController::addMetarAtPath(const string& propPath, const string&
 
   SGPropertyNode_ptr metarNode = fgGetNode(propPath, true);
   SG_LOG( SG_ENVIRONMENT, SG_INFO, "Adding metar properties at " << propPath );
-  LiveMetarProperties_ptr p(new LiveMetarProperties( metarNode, _requester ));
+  LiveMetarProperties_ptr p(new LiveMetarProperties( metarNode, _requester, getMetarMaxAgeMin() ));
   _metarProperties.push_back(p);
   p->setStationId(icao);
 }
@@ -340,7 +364,7 @@ void BasicRealWxController::checkNearbyMetar()
               _metarProperties[0]->getStationId() <<
               "', new: '" << nearestAirport->ident() << "'" );
           _metarProperties[0]->setStationId( nearestAirport->ident() );
-          _metarProperties[0]->setTimeToLive( 0.0 );
+          _metarProperties[0]->resetTimeToLive();
       }
     }
     catch( sg_exception & ) {
@@ -419,6 +443,11 @@ void NoaaMetarRealWxController::requestMetar( MetarDataHandler * metarDataHandle
                   SG_LOG(SG_ENVIRONMENT, SG_WARN, "metar download failed:" << url() << ": reason:" << responseReason());
               }
           }
+        
+        virtual void failed()
+        {
+            SG_LOG(SG_ENVIRONMENT, SG_INFO, "metar download failure");
+        }
 
 //          bool fromMetarProxy() const
 //          { return _fromProxy; }