mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 02:20:04 +00:00 
			
		
		
		
	Handle received alerts and test against location for playing alert audio
This commit is contained in:
		
							parent
							
								
									dd79f9208d
								
							
						
					
					
						commit
						40fc8ade20
					
				
					 2 changed files with 108 additions and 3 deletions
				
			
		|  | @ -1,10 +1,16 @@ | |||
| #include <scwx/qt/manager/alert_manager.hpp> | ||||
| #include <scwx/qt/manager/media_manager.hpp> | ||||
| #include <scwx/qt/manager/position_manager.hpp> | ||||
| #include <scwx/qt/manager/text_event_manager.hpp> | ||||
| #include <scwx/qt/settings/audio_settings.hpp> | ||||
| #include <scwx/qt/types/location_types.hpp> | ||||
| #include <scwx/qt/util/geographic_lib.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <boost/asio/post.hpp> | ||||
| #include <boost/asio/thread_pool.hpp> | ||||
| #include <boost/uuid/random_generator.hpp> | ||||
| #include <QGeoPositionInfo> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -28,23 +34,119 @@ public: | |||
| 
 | ||||
|       audioSettings.alert_location_method().RegisterValueChangedCallback( | ||||
|          [this](const std::string& value) { UpdateLocationTracking(value); }); | ||||
| 
 | ||||
|       QObject::connect( | ||||
|          textEventManager_.get(), | ||||
|          &manager::TextEventManager::AlertUpdated, | ||||
|          self_, | ||||
|          [this](const types::TextEventKey& key, size_t messageIndex) | ||||
|          { | ||||
|             boost::asio::post(threadPool_, | ||||
|                               [=, this]() { HandleAlert(key, messageIndex); }); | ||||
|          }); | ||||
|    } | ||||
| 
 | ||||
|    ~Impl() {} | ||||
|    ~Impl() { threadPool_.join(); } | ||||
| 
 | ||||
|    common::Coordinate CurrentCoordinate() const; | ||||
|    void HandleAlert(const types::TextEventKey& key, size_t messageIndex) const; | ||||
|    void UpdateLocationTracking(const std::string& value) const; | ||||
| 
 | ||||
|    boost::asio::thread_pool threadPool_ {1u}; | ||||
| 
 | ||||
|    AlertManager* self_; | ||||
| 
 | ||||
|    boost::uuids::uuid uuid_ {boost::uuids::random_generator()()}; | ||||
| 
 | ||||
|    std::shared_ptr<MediaManager>    mediaManager_ {MediaManager::Instance()}; | ||||
|    std::shared_ptr<PositionManager> positionManager_ { | ||||
|       PositionManager::Instance()}; | ||||
|    std::shared_ptr<TextEventManager> textEventManager_ { | ||||
|       TextEventManager::Instance()}; | ||||
| }; | ||||
| 
 | ||||
| AlertManager::AlertManager() : p(std::make_unique<Impl>(this)) {} | ||||
| AlertManager::~AlertManager() = default; | ||||
| 
 | ||||
| common::Coordinate AlertManager::Impl::CurrentCoordinate() const | ||||
| { | ||||
|    settings::AudioSettings& audioSettings = settings::AudioSettings::Instance(); | ||||
|    common::Coordinate       coordinate {}; | ||||
| 
 | ||||
|    types::LocationMethod locationMethod = types::GetLocationMethod( | ||||
|       audioSettings.alert_location_method().GetValue()); | ||||
| 
 | ||||
|    if (locationMethod == types::LocationMethod::Fixed) | ||||
|    { | ||||
|       coordinate.latitude_  = audioSettings.alert_latitude().GetValue(); | ||||
|       coordinate.longitude_ = audioSettings.alert_longitude().GetValue(); | ||||
|    } | ||||
|    else if (locationMethod == types::LocationMethod::Track) | ||||
|    { | ||||
|       QGeoPositionInfo position = positionManager_->position(); | ||||
|       if (position.isValid()) | ||||
|       { | ||||
|          QGeoCoordinate trackedCoordinate = position.coordinate(); | ||||
|          coordinate.latitude_             = trackedCoordinate.latitude(); | ||||
|          coordinate.longitude_            = trackedCoordinate.longitude(); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    return coordinate; | ||||
| } | ||||
| 
 | ||||
| void AlertManager::Impl::HandleAlert(const types::TextEventKey& key, | ||||
|                                      size_t messageIndex) const | ||||
| { | ||||
|    // Skip alert if there are more messages to be processed
 | ||||
|    if (messageIndex + 1 < textEventManager_->message_count(key)) | ||||
|    { | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    settings::AudioSettings& audioSettings = settings::AudioSettings::Instance(); | ||||
|    common::Coordinate       currentCoordinate = CurrentCoordinate(); | ||||
| 
 | ||||
|    auto message = textEventManager_->message_list(key).at(messageIndex); | ||||
| 
 | ||||
|    for (auto& segment : message->segments()) | ||||
|    { | ||||
|       if (!segment->codedLocation_.has_value()) | ||||
|       { | ||||
|          continue; | ||||
|       } | ||||
| 
 | ||||
|       auto&             vtec       = segment->header_->vtecString_.front(); | ||||
|       auto              action     = vtec.pVtec_.action(); | ||||
|       awips::Phenomenon phenomenon = vtec.pVtec_.phenomenon(); | ||||
|       auto              eventEnd   = vtec.pVtec_.event_end(); | ||||
|       bool alertActive             = (action != awips::PVtec::Action::Canceled); | ||||
| 
 | ||||
|       // If the event has ended or is inactive, or if the alert is not enabled,
 | ||||
|       // skip it
 | ||||
|       if (eventEnd < std::chrono::system_clock::now() || !alertActive || | ||||
|           !audioSettings.alert_enabled(phenomenon).GetValue()) | ||||
|       { | ||||
|          continue; | ||||
|       } | ||||
| 
 | ||||
|       // Determine if the alert is active at the current coordinte
 | ||||
|       auto alertCoordinates = segment->codedLocation_->coordinates(); | ||||
| 
 | ||||
|       if (util::GeographicLib::AreaContainsPoint(alertCoordinates, | ||||
|                                                  currentCoordinate)) | ||||
|       { | ||||
|          logger_->info("Alert active at current location: {} {}.{} {}", | ||||
|                        vtec.pVtec_.office_id(), | ||||
|                        awips::GetPhenomenonCode(vtec.pVtec_.phenomenon()), | ||||
|                        awips::PVtec::GetActionCode(vtec.pVtec_.action()), | ||||
|                        vtec.pVtec_.event_tracking_number()); | ||||
| 
 | ||||
|          mediaManager_->Play(types::AudioFile::EasAttentionSignal); | ||||
|       } | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void AlertManager::Impl::UpdateLocationTracking( | ||||
|    const std::string& locationMethodName) const | ||||
| { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat