diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index 6747cf1..deaeaf6 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -115,6 +115,10 @@ static double formatCourse(double cv) { return m / 1852; } + static double mtr2nm(double m) + { + return m / 1852; + } static double kelvinToC(double v){ return v-273.15; @@ -148,6 +152,11 @@ class GwBoatData{ GWBOATDATA(double,WaterDepth,4000,NULL) GWBOATDATA(double,SecondsSinceMidnight,4000,NULL) GWBOATDATA(double,WaterTemperature,4000,&kelvinToC) + GWBOATDATA(double,XTE,4000,NULL) + GWBOATDATA(double,DTW,4000,&mtr2nm) + GWBOATDATA(double,BTW,4000,&formatCourse) + GWBOATDATA(double,WPLatitude,4000,NULL) + GWBOATDATA(double,WPLongitude,4000,NULL) GWBOATDATA(uint32_t,Log,0,&mtr2nm) GWBOATDATA(uint32_t,TripLog,0,&mtr2nm) GWBOATDATA(uint32_t,DaysSince1970,4000,NULL) diff --git a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp index f6d6008..ef4af8b 100644 --- a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp +++ b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp @@ -47,7 +47,43 @@ private: double dummy = 0; ConverterList converters; std::map lastSends; + class WaypointNumber{ + public: + unsigned long id; + unsigned long lastUsed; + WaypointNumber(){} + WaypointNumber(unsigned long id,unsigned long ts){ + this->id=id; + this->lastUsed=ts; + } + }; + std::map waypointMap; + unsigned long waypointId=0; + const size_t MAXWAYPOINTS=100; + unsigned long getWaypointId(const char *name){ + String wpName(name); + auto it=waypointMap.find(wpName); + if (it != waypointMap.end()){ + it->second.lastUsed=millis(); + return it->second.id; + } + unsigned long now=millis(); + auto oldestIt=waypointMap.begin(); + if (waypointMap.size() > MAXWAYPOINTS){ + LOG_DEBUG(GwLog::DEBUG+1,"removing oldest from waypoint map"); + for (it=waypointMap.begin();it!=waypointMap.end();it++){ + if (oldestIt->second.lastUsed > it->second.lastUsed){ + oldestIt=it; + } + } + waypointMap.erase(oldestIt); + } + waypointId++; + WaypointNumber newWp(waypointId,now); + waypointMap[wpName]=newWp; + return newWp.id; + } bool send(tN2kMsg &msg,unsigned long minDiff=50){ unsigned long now=millis(); unsigned long pgn=msg.PGN; @@ -82,6 +118,58 @@ private: void convertRMB(const SNMEA0183Msg &msg) { LOG_DEBUG(GwLog::DEBUG + 1, "convert RMB"); + tRMB rmb; + if (! NMEA0183ParseRMB_nc(msg,rmb)){ + logger->logDebug(GwLog::DEBUG, "failed to parse RMC %s", msg.line); + return; + } + tN2kMsg n2kMsg; + if (boatData->XTE->update(rmb.xte,msg.sourceId)){ + tN2kXTEMode mode=N2kxtem_Autonomous; + if (msg.FieldCount() > 13){ + const char *modeChar=msg.Field(13); + switch(*modeChar){ + case 'D': + mode=N2kxtem_Differential; + break; + case 'E': + mode=N2kxtem_Estimated; + break; + case 'M': + mode=N2kxtem_Manual; + break; + case 'S': + mode=N2kxtem_Simulator; + break; + default: + break; + + } + } + SetN2kXTE(n2kMsg,1,mode,false,rmb.xte); + send(n2kMsg); + } + if (boatData->DTW->update(rmb.dtw,msg.sourceId) + && boatData->BTW->update(rmb.btw,msg.sourceId) + && boatData->WPLatitude->update(rmb.latitude,msg.sourceId) + && boatData->WPLongitude->update(rmb.longitude,msg.sourceId) + ){ + SetN2kNavigationInfo(n2kMsg,1,rmb.dtw,N2khr_true, + false, + (rmb.arrivalAlarm == 'A'), + N2kdct_GreatCircle, //see e.g. https://manuals.bandg.com/discontinued/NMEA_FFD_User_Manual.pdf pg 21 + N2kDoubleNA, + N2kUInt16NA, + N2kDoubleNA, + rmb.btw, + getWaypointId(rmb.originID), + getWaypointId(rmb.destID), + rmb.latitude, + rmb.longitude, + rmb.vmg + ); + send(n2kMsg); + } } #define UD(item) updateDouble(boatData->item, item, msg.sourceId) #define UI(item) updateUint32(boatData->item, item, msg.sourceId) @@ -127,10 +215,11 @@ private: #define CVL [](const SNMEA0183Msg &msg, NMEA0183DataToN2KFunctions *p) -> void void registerConverters() { - converters.registerConverter(129283UL, String(F("RMB")), &NMEA0183DataToN2KFunctions::convertRMB); + converters.registerConverter(129283UL,129284UL,129285UL, + String(F("RMB")), &NMEA0183DataToN2KFunctions::convertRMB); converters.registerConverter( - 126992UL,129025UL,129026UL,127258UL, String(F("RMC")), - &NMEA0183DataToN2KFunctions::convertRMC); + 126992UL,129025UL,129026UL,127258UL, + String(F("RMC")), &NMEA0183DataToN2KFunctions::convertRMC); } public: