diff --git a/lib/boatData/GwBoatData.cpp b/lib/boatData/GwBoatData.cpp index 50fd583..25fb004 100644 --- a/lib/boatData/GwBoatData.cpp +++ b/lib/boatData/GwBoatData.cpp @@ -12,6 +12,7 @@ public: static int getType(const double &x) { return GWTYPE_DOUBLE; } static int getType(const String &x) { return GWTYPE_STRING; } static int getType(const GwSatInfoList &x) { return GWTYPE_USER + 1; } + static int getType(const GwAisTargetList &x) { return GWTYPE_USER + 1; } }; bool GwBoatItemBase::isValid(unsigned long now) const @@ -289,6 +290,7 @@ template class GwBoatItem; template class GwBoatItem; template class GwBoatItem; template class GwBoatItem; + void GwSatInfoList::houseKeeping(unsigned long ts) { if (ts == 0) @@ -302,6 +304,7 @@ void GwSatInfoList::houseKeeping(unsigned long ts) }), sats.end()); } + void GwSatInfoList::update(GwSatInfo entry, unsigned long validTill) { entry.validTill = validTill; @@ -344,6 +347,63 @@ void GwBoatDataSatList::toJsonDoc(GwJsonDocument *doc, unsigned long minTime) GwBoatItem::toJsonDoc(doc, minTime); } +void GwAisTargetList::houseKeeping(unsigned long ts) +{ + if (ts == 0) { + ts = millis(); + } + targets.erase( + std::remove_if( + targets.begin(), + targets.end(), + [ts, this](const GwAisTarget &target) { + return target.validTill < ts; + } + ), + targets.end() + ); +} + +void GwAisTargetList::update(GwAisTarget target, unsigned long validTill) +{ + target.validTill = validTill; + for (auto it = targets.begin(); it != targets.end(); it++) { + if (it->mmsi == target.mmsi) { + *it = target; + houseKeeping(); + return; + } + } + houseKeeping(); + targets.push_back(target); +} + +GwBoatDataAisList::GwBoatDataAisList(String name, String formatInfo, GwBoatItemBase::TOType toType, GwBoatItemMap *map) : GwBoatItem(name, formatInfo, toType, map) {} + +bool GwBoatDataAisList::update(GwAisTarget target, int source) +{ + unsigned long now = millis(); + if (isValid(now)) + { + //priority handling + //sources with lower ids will win + //and we will not overwrite their value + if (lastUpdateSource < source) + { + return false; + } + } + lastUpdateSource = source; + uls(now); + data.update(target, now+invalidTime); + return true; +} +void GwBoatDataAisList::toJsonDoc(GwJsonDocument *doc, unsigned long minTime) +{ + data.houseKeeping(); + GwBoatItem::toJsonDoc(doc, minTime); +} + GwBoatData::GwBoatData(GwLog *logger, GwConfigHandler *cfg) { this->logger = logger; @@ -513,6 +573,11 @@ bool convertToJson(const GwSatInfoList &si, JsonVariant &variant) return variant.set(si.getNumSats()); } +bool convertToJson(const GwAisTargetList &si, JsonVariant &variant) +{ + return variant.set(si.getNumTargets()); +} + #ifdef _UNDEF #include diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index 5c5cbbd..9efb23b 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -196,6 +196,55 @@ public: }; +class GwAisTarget { +public: + uint32_t mmsi; + char callsign[8]; + char name[21]; + uint8_t vesseltype; + double lat; + double lon; + float length; + float beam; + float sog; + float cog; + unsigned long validTill; +}; + +class GwAisTargetList { +public: + static const GwBoatItemBase::TOType toType=GwBoatItemBase::TOType::ais; + std::vector targets; + void houseKeeping(unsigned long ts=0); + void update(GwAisTarget target, unsigned long validTill); + int getNumTargets() const { + return targets.size(); + } + GwAisTarget *getAt(int idx){ + if (idx >= 0 && idx < targets.size()) return &targets.at(idx); + return NULL; + } + operator double(){ return getNumTargets();} +}; + +class GwBoatDataAisList : public GwBoatItem { +public: + GwBoatDataAisList(String name, String formatInfo, GwBoatItemBase::TOType toType, GwBoatItemMap *map = NULL); + bool update(GwAisTarget target, int source); + virtual void toJsonDoc(GwJsonDocument *doc, unsigned long minTime); + GwAisTarget *getAt(int idx) { + if (! isValid()) return NULL; + return data.getAt(idx); + } + int getNumTargets(){ + if (! isValid()) return 0; + return data.getNumTargets(); + } + virtual double getDoubleValue(){ + return (double)(data.getNumTargets()); + } +}; + class GwBoatItemNameProvider { public: @@ -256,6 +305,7 @@ class GwBoatData{ GWBOATDATA(double,WPLon,formatLongitude) // waypoint longitude GWBOATDATA(String,WPName,formatName) // waypoint name GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::toType,formatFixed0); + GWSPECBOATDATA(GwBoatDataAisList,AisTarget,GwAisTargetList::toType,formatFixed0); public: GwBoatData(GwLog *logger, GwConfigHandler *cfg); ~GwBoatData();