Przeglądaj źródła

send aircraft reports

Sven Czarnian 3 lat temu
rodzic
commit
25c6a1fa86
2 zmienionych plików z 102 dodań i 4 usunięć
  1. 99 4
      src/PlugIn.cpp
  2. 3 0
      src/PlugIn.h

+ 99 - 4
src/PlugIn.cpp

@@ -15,9 +15,12 @@
 #include <Shlwapi.h>
 #include <Windows.h>
 
+#include <aman/com/AircraftReporter.h>
 #include <aman/config/CommunicationFileFormat.h>
 #include <aman/config/IdentifierFileFormat.h>
 
+#include <protobuf/AircraftReport.pb.h>
+
 #include "PlugIn.h"
 
 EXTERN_C IMAGE_DOS_HEADER __ImageBase;
@@ -31,6 +34,8 @@ PlugIn::PlugIn() :
                                  PLUGIN_DEVELOPER,
                                  PLUGIN_COPYRIGHT),
         m_configuration() {
+    GOOGLE_PROTOBUF_VERIFY_VERSION;
+
     this->DisplayUserMessage(PLUGIN_NAME, "INFO", (std::string("Loaded ") + PLUGIN_NAME + " " + PLUGIN_VERSION).c_str(), true, true, false, false, false);
 
     /* get the dll-path */
@@ -53,9 +58,17 @@ PlugIn::PlugIn() :
         this->DisplayUserMessage(PLUGIN_NAME, "ERROR", ("AmanIdentity.txt:" + std::to_string(identFormat.errorLine()) + " - " + identFormat.errorMessage()).c_str(), true, true, true, true, true);
         return;
     }
+
+    if (false == AircraftReporter::instance().initialize(this->m_configuration)) {
+        this->DisplayUserMessage(PLUGIN_NAME, "ERROR", "Unable to initialize the reporter-connection to the backend", true, true, true, true, true);
+        return;
+    }
 }
 
-PlugIn::~PlugIn() noexcept { }
+PlugIn::~PlugIn() noexcept {
+    AircraftReporter::instance().deinitialize();
+    google::protobuf::ShutdownProtobufLibrary();
+}
 
 EuroScopePlugIn::CRadarScreen* PlugIn::OnRadarScreenCreated(const char* displayName, bool needsRadarContent, bool geoReferenced,
     bool canBeSaved, bool canBeCreated) {
@@ -71,6 +84,42 @@ EuroScopePlugIn::CRadarScreen* PlugIn::OnRadarScreenCreated(const char* displayN
     return this->m_screen.get();
 }
 
+aman::Aircraft* PlugIn::generateAircraftMessage(const EuroScopePlugIn::CRadarTarget& target) {
+    if (false == target.IsValid() || false == target.GetCorrelatedFlightPlan().IsValid())
+        return nullptr;
+
+    auto flightPlan = target.GetCorrelatedFlightPlan();
+    std::string callsign(target.GetCallsign());
+    aman::Aircraft* retval = new aman::Aircraft();
+
+    /* fill all available information */
+    retval->set_callsign(callsign);
+    if (3 <= callsign.length())
+        retval->set_airline(callsign.substr(0, 3));
+    retval->set_type(flightPlan.GetFlightPlanData().GetAircraftFPType());
+    retval->set_wtc(std::to_string(flightPlan.GetFlightPlanData().GetAircraftWtc()));
+    /* TODO get recat */
+    retval->set_enginecount(flightPlan.GetFlightPlanData().GetEngineNumber());
+
+    switch (flightPlan.GetFlightPlanData().GetEngineType()) {
+    case 'P':
+    case 'T':
+        retval->set_enginetype(aman::Aircraft_EngineType::Aircraft_EngineType_TURBOPROB);
+        break;
+    case 'E':
+        retval->set_enginetype(aman::Aircraft_EngineType::Aircraft_EngineType_ELECTRIC);
+        break;
+    case 'J':
+        retval->set_enginetype(aman::Aircraft_EngineType::Aircraft_EngineType_JET);
+        break;
+    default:
+        retval->set_enginetype(aman::Aircraft_EngineType::Aircraft_EngineType_UNKNOWN);
+        break;
+    }
+
+    return retval;
+}
+
 void PlugIn::OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget radarTarget) {
     /* ignore invalid targets */
     if (false == radarTarget.IsValid())
@@ -90,15 +139,61 @@ void PlugIn::OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget radarTarg
     if (nullptr == flightPlan.GetFlightPlanData().GetPlanType() || 'I' != *flightPlan.GetFlightPlanData().GetPlanType())
         return;
 
+    /* filter invalid destinations */
+    auto destination = std::string_view(flightPlan.GetFlightPlanData().GetDestination());
+    if (4 != destination.length())
+        return;
+
+    /* TODO temporary filter */
+    if ("EDDB" != destination)
+        return;
+
     /* filter by distance to destination */
     double distanceNM = flightPlan.GetDistanceToDestination();
-    if (250.0 < distanceNM)
+    if (5.0 > distanceNM || 250.0 < distanceNM)
         return;
 
     /* filter by airborne identifier (assume a GS>50kn and a big distance to the origin) */
     if (50 > radarTarget.GetGS() || 10.0 > flightPlan.GetDistanceFromOrigin())
         return;
 
-    /* TODO generate protobuf message */
-    /* TODO send aircraft update */
+    /* generate protobuf message */
+    aman::Aircraft* aircraft = this->generateAircraftMessage(radarTarget);
+    if (nullptr == aircraft)
+        return;
+    aman::Dynamics* dynamics = new aman::Dynamics();
+    dynamics->set_altitude(radarTarget.GetPosition().GetFlightLevel());
+    dynamics->set_groundspeed(radarTarget.GetGS());
+    dynamics->set_verticalspeed(radarTarget.GetVerticalSpeed());
+    aman::Coordinate* coordinate = new aman::Coordinate();
+    coordinate->set_latitude(radarTarget.GetPosition().GetPosition().m_Latitude);
+    coordinate->set_longitude(radarTarget.GetPosition().GetPosition().m_Longitude);
+
+    /* create the report */
+    aman::AircraftReport report;
+    if (2 <= flightPlan.GetExtractedRoute().GetPointsNumber()) {
+        int lastIdx = flightPlan.GetExtractedRoute().GetPointsNumber() - 2;
+
+        auto timeAtIAF = std::chrono::utc_clock::now();
+        timeAtIAF += std::chrono::minutes(flightPlan.GetExtractedRoute().GetPointDistanceInMinutes(lastIdx));
+
+        std::stringstream stream;
+        stream << std::format("{0:%y%m%d%H%M}", timeAtIAF);
+        report.set_timeatiaf(stream.str());
+
+        report.set_initialapproachfix(std::string(flightPlan.GetExtractedRoute().GetPointName(lastIdx)));
+    }
+    report.set_destination(std::string(destination));
+    report.set_allocated_aircraft(aircraft);
+    report.set_allocated_dynamics(dynamics);
+    report.set_allocated_position(coordinate);
+
+    /* serialize the report */
+    std::string serialized = report.SerializeAsString();
+    zmq::message_t message(serialized.size());
+    std::memcpy(message.data(), serialized.c_str(), serialized.size());
+
+    /* send the report */
+    if (false == AircraftReporter::instance().send(message))
+        this->DisplayUserMessage(PLUGIN_NAME, "ERROR", ("Unable to send a report for " + aircraft->callsign()).c_str(), true, true, true, true, true);
 }

+ 3 - 0
src/PlugIn.h

@@ -15,6 +15,7 @@
 #pragma warning(pop)
 
 #include <aman/types/Communication.h>
+#include <protobuf/AircraftReport.pb.h>
 
 #include "RadarScreen.h"
 
@@ -35,6 +36,8 @@ namespace aman {
         enum class TagItemElement {
         };
 
+        aman::Aircraft* generateAircraftMessage(const EuroScopePlugIn::CRadarTarget& target);
+
         Communication                m_configuration;
         std::shared_ptr<RadarScreen> m_screen;