Handle received alerts and test against location for playing alert audio

This commit is contained in:
Dan Paulat 2023-12-02 07:44:27 -06:00
parent dd79f9208d
commit 40fc8ade20
2 changed files with 108 additions and 3 deletions

View file

@ -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
{