From 54d6d51519a65c8cab6af187a8286d85b5ded2a1 Mon Sep 17 00:00:00 2001 From: quantenschaum Date: Wed, 21 Aug 2024 14:57:36 +0200 Subject: [PATCH 1/5] tried to fix wind conversion, disabled wind calculation --- lib/boatData/GwBoatData.h | 53 +++++++++++++------------ lib/nmea0183ton2k/NMEA0183DataToN2K.cpp | 37 ++++++++--------- lib/nmea2kto0183/N2kDataToNMEA0183.cpp | 41 +++++++++++-------- 3 files changed, 69 insertions(+), 62 deletions(-) diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index 6d3ab19..fd57a87 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -175,41 +175,42 @@ class GwBoatData{ GwBoatItemBase::GwBoatItemMap values; public: - GWBOATDATA(double,COG,4000,formatCourse) - GWBOATDATA(double,TWD,4000,formatCourse) - GWBOATDATA(double,SOG,4000,formatKnots) - GWBOATDATA(double,STW,4000,formatKnots) - GWBOATDATA(double,TWS,4000,formatKnots) - GWBOATDATA(double,AWS,4000,formatKnots) - GWBOATDATA(double,MaxTws,0,formatKnots) + GWBOATDATA(double,COG,4000,formatCourse) // course over ground + GWBOATDATA(double,SOG,4000,formatKnots) // speed over ground + GWBOATDATA(double,HDG,4000,formatCourse) // true heading + GWBOATDATA(double,MHDG,4000,formatCourse) // magnetic heading + GWBOATDATA(double,STW,4000,formatKnots) // water speed + GWBOATDATA(double,VAR,4000,formatCourse) // variation + GWBOATDATA(double,DEV,4000,formatCourse) // deviation + GWBOATDATA(double,AWA,4000,formatWind) // apparent wind ANGLE + GWBOATDATA(double,AWS,4000,formatKnots) // apparent wind speed GWBOATDATA(double,MaxAws,0,formatKnots) - GWBOATDATA(double,AWA,4000,formatWind) - GWBOATDATA(double,HDG,4000,formatCourse) //true heading - GWBOATDATA(double,MHDG,4000,formatCourse) //magnetic heading - GWBOATDATA(double,ROT,4000,formatRot) - GWBOATDATA(double,VAR,4000,formatCourse) //Variation - GWBOATDATA(double,DEV,4000,formatCourse) //Deviation + GWBOATDATA(double,TWD,4000,formatCourse) // true wind DIRECTION + GWBOATDATA(double,TWA,4000,formatCourse) // true wind ANGLE + GWBOATDATA(double,TWS,4000,formatKnots) // true wind speed + GWBOATDATA(double,MaxTws,0,formatKnots) + GWBOATDATA(double,ROT,4000,formatRot) // rate of turn + GWBOATDATA(double,RPOS,4000,formatWind) // rudder position + GWBOATDATA(double,PRPOS,4000,formatWind) // secondary rudder position + GWBOATDATA(double,LAT,4000,formatLatitude) + GWBOATDATA(double,LON,4000,formatLongitude) + GWBOATDATA(double,ALT,4000,formatFixed0) //altitude GWBOATDATA(double,HDOP,4000,formatDop) GWBOATDATA(double,PDOP,4000,formatDop) GWBOATDATA(double,VDOP,4000,formatDop) - GWBOATDATA(double,RPOS,4000,formatWind) //RudderPosition - GWBOATDATA(double,PRPOS,4000,formatWind) //second rudder pos - GWBOATDATA(double,LAT,4000,formatLatitude) - GWBOATDATA(double,LON,4000,formatLongitude) - GWBOATDATA(double,ALT,4000,formatFixed0) //altitude GWBOATDATA(double,DBS,4000,formatDepth) //waterDepth (below surface) GWBOATDATA(double,DBT,4000,formatDepth) //DepthTransducer - GWBOATDATA(double,GPST,4000,formatTime) //GpsTime + GWBOATDATA(double,GPST,4000,formatTime) // GPS time (seconds of day) + GWBOATDATA(uint32_t,GPSD,4000,formatDate) // GPS date (days since 1979-01-01) + GWBOATDATA(int16_t,TZ,8000,formatFixed0) GWBOATDATA(double,WTemp,4000,kelvinToC) - GWBOATDATA(double,XTE,4000,formatXte) - GWBOATDATA(double,DTW,4000,mtr2nm) //distance wp - GWBOATDATA(double,BTW,4000,formatCourse) //bearing wp - GWBOATDATA(double,WPLat,4000,formatLatitude) - GWBOATDATA(double,WPLon,4000,formatLongitude) GWBOATDATA(uint32_t,Log,16000,mtr2nm) GWBOATDATA(uint32_t,TripLog,16000,mtr2nm) - GWBOATDATA(uint32_t,GPSD,4000,formatDate) //Date - GWBOATDATA(int16_t,TZ,8000,formatFixed0) + GWBOATDATA(double,DTW,4000,mtr2nm) // distance to waypoint + GWBOATDATA(double,BTW,4000,formatCourse) // bearing to waypoint + GWBOATDATA(double,XTE,4000,formatXte) // cross track error + GWBOATDATA(double,WPLat,4000,formatLatitude) // waypoint latitude + GWBOATDATA(double,WPLon,4000,formatLongitude) // waypoint longitude GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::lifeTime,formatFixed0); public: GwBoatData(GwLog *logger); diff --git a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp index bfed8fd..8477ab8 100644 --- a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp +++ b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp @@ -399,20 +399,20 @@ private: return; } tN2kMsg n2kMsg; - tN2kWindReference n2kRef; + tN2kWindReference n2kRef; bool shouldSend=false; WindAngle=formatDegToRad(WindAngle); switch(Reference){ case NMEA0183Wind_Apparent: n2kRef=N2kWind_Apparent; shouldSend=updateDouble(boatData->AWA,WindAngle,msg.sourceId) && - updateDouble(boatData->AWS,WindSpeed,msg.sourceId); + updateDouble(boatData->AWS,WindSpeed,msg.sourceId); if (WindSpeed != NMEA0183DoubleNA) boatData->MaxAws->updateMax(WindSpeed); break; case NMEA0183Wind_True: - n2kRef=N2kWind_True_North; - shouldSend=updateDouble(boatData->TWD,WindAngle,msg.sourceId) && - updateDouble(boatData->TWS,WindSpeed,msg.sourceId); + n2kRef=N2kWind_True_water; + shouldSend=updateDouble(boatData->TWA,WindAngle,msg.sourceId) && + updateDouble(boatData->TWS,WindSpeed,msg.sourceId); if (WindSpeed != NMEA0183DoubleNA) boatData->MaxTws->updateMax(WindSpeed); break; default: @@ -467,8 +467,7 @@ private: void convertMWD(const SNMEA0183Msg &msg) { - double WindAngle = NMEA0183DoubleNA, WindAngleMagnetic=NMEA0183DoubleNA, - WindSpeed = NMEA0183DoubleNA; + double WindDirection = NMEA0183DoubleNA, WindDirectionMagnetic=NMEA0183DoubleNA, WindSpeed = NMEA0183DoubleNA; if (msg.FieldCount() < 8 ) { LOG_DEBUG(GwLog::DEBUG, "failed to parse MWD %s", msg.line); @@ -476,11 +475,11 @@ private: } if (msg.FieldLen(0) > 0 && msg.Field(1)[0] == 'T') { - WindAngle = formatDegToRad(atof(msg.Field(0))); + WindDirection = formatDegToRad(atof(msg.Field(0))); } if (msg.FieldLen(2) > 0 && msg.Field(3)[0] == 'M') { - WindAngleMagnetic = formatDegToRad(atof(msg.Field(2))); + WindDirectionMagnetic = formatDegToRad(atof(msg.Field(2))); } if (msg.FieldLen(4) > 0 && msg.Field(5)[0] == 'N') { @@ -497,19 +496,17 @@ private: } tN2kMsg n2kMsg; bool shouldSend = false; - if (WindAngle != NMEA0183DoubleNA){ - shouldSend = updateDouble(boatData->TWD, WindAngle, msg.sourceId) && + if (WindDirection != NMEA0183DoubleNA){ + shouldSend = updateDouble(boatData->TWD, WindDirection, msg.sourceId) && updateDouble(boatData->TWS, WindSpeed, msg.sourceId); if (WindSpeed != NMEA0183DoubleNA) boatData->MaxTws->updateMax(WindSpeed); - } - if (shouldSend) - { - SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngle, N2kWind_True_North); - send(n2kMsg,msg.sourceId,String(n2kMsg.PGN)+String((int)N2kWind_True_North)); - } - if (WindAngleMagnetic != NMEA0183DoubleNA && shouldSend){ - SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngleMagnetic, N2kWind_Magnetic); - send(n2kMsg,msg.sourceId,String(n2kMsg.PGN)+String((int)N2kWind_Magnetic)); + if(shouldSend && boatData->HDG->isValid()) { + double twa = WindDirection-boatData->HDG->getData(); + if(twa<0) { twa+=2*M_PI; } + updateDouble(boatData->TWA, twa, msg.sourceId); + SetN2kWindSpeed(n2kMsg, 1, WindSpeed, twa, N2kWind_True_water); + send(n2kMsg,msg.sourceId,String(n2kMsg.PGN)+String((int)N2kWind_True_water)); + } } } diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp index 26c6811..b08ac7d 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp @@ -468,37 +468,46 @@ private: { unsigned char SID; tN2kWindReference WindReference; - tNMEA0183WindReference NMEA0183Reference = NMEA0183Wind_True; - - double x, y; double WindAngle=N2kDoubleNA, WindSpeed=N2kDoubleNA; - if (ParseN2kWindSpeed(N2kMsg, SID, WindSpeed, WindAngle, WindReference)) - { + if (ParseN2kWindSpeed(N2kMsg, SID, WindSpeed, WindAngle, WindReference)) { tNMEA0183Msg NMEA0183Msg; + tNMEA0183WindReference NMEA0183Reference; + bool shouldSend = false; - if (WindReference == N2kWind_Apparent) - { + // MWV sentence contains apparent/true ANGLE and SPEED + // https://gpsd.gitlab.io/gpsd/NMEA.html#_mwv_wind_speed_and_angle + // https://docs.vaisala.com/r/M211109EN-L/en-US/GUID-7402DEF8-5E82-446F-B63E-998F49F3D743/GUID-C77934C7-2A72-466E-BC52-CE6B8CC7ACB6 + + if (WindReference == N2kWind_Apparent) { NMEA0183Reference = NMEA0183Wind_Apparent; updateDouble(boatData->AWA, WindAngle); updateDouble(boatData->AWS, WindSpeed); setMax(boatData->MaxAws, boatData->AWS); - } - if (WindReference == N2kWind_True_North) - { + shouldSend = true; + } + if (WindReference == N2kWind_True_water) { NMEA0183Reference = NMEA0183Wind_True; - updateDouble(boatData->TWD, WindAngle); + updateDouble(boatData->TWA, WindAngle); updateDouble(boatData->TWS, WindSpeed); + setMax(boatData->MaxTws, boatData->TWS); + shouldSend = true; + if (boatData->HDG->isValid()) { + double twd = WindAngle+boatData->HDG->getData(); + if (twd>2*M_PI) { twd-=2*M_PI; } + updateDouble(boatData->TWD, twd); + } } - if (NMEA0183SetMWV(NMEA0183Msg, formatCourse(WindAngle), NMEA0183Reference, WindSpeed,talkerId)) + if (shouldSend && NMEA0183SetMWV(NMEA0183Msg, formatCourse(WindAngle), NMEA0183Reference, WindSpeed, talkerId)) { SendMessage(NMEA0183Msg); + } - if (WindReference == N2kWind_Apparent && boatData->SOG->isValid()) + /* if (WindReference == N2kWind_Apparent && boatData->SOG->isValid()) { // Lets calculate and send TWS/TWA if SOG is available - x = WindSpeed * cos(WindAngle); - y = WindSpeed * sin(WindAngle); + double x = WindSpeed * cos(WindAngle); + double y = WindSpeed * sin(WindAngle); updateDouble(boatData->TWD, atan2(y, -boatData->SOG->getData() + x)); updateDouble(boatData->TWS, sqrt((y * y) + ((-boatData->SOG->getData() + x) * (-boatData->SOG->getData() + x)))); @@ -534,7 +543,7 @@ private: return; SendMessage(NMEA0183Msg); - } + } */ } } //***************************************************************************** From 1fa10497594d4155fc4b345b6443f870c248bf68 Mon Sep 17 00:00:00 2001 From: quantenschaum Date: Thu, 22 Aug 2024 15:16:23 +0200 Subject: [PATCH 2/5] renamed HDG->HDT, MHDG->HDM --- lib/boatData/GwBoatData.h | 4 +-- lib/nmea0183ton2k/NMEA0183DataToN2K.cpp | 35 +++++++++++++------------ lib/nmea2kto0183/N2kDataToNMEA0183.cpp | 16 +++++------ 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index fd57a87..b4df0ec 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -177,8 +177,8 @@ class GwBoatData{ GWBOATDATA(double,COG,4000,formatCourse) // course over ground GWBOATDATA(double,SOG,4000,formatKnots) // speed over ground - GWBOATDATA(double,HDG,4000,formatCourse) // true heading - GWBOATDATA(double,MHDG,4000,formatCourse) // magnetic heading + GWBOATDATA(double,HDT,4000,formatCourse) // true heading + GWBOATDATA(double,HDM,4000,formatCourse) // magnetic heading GWBOATDATA(double,STW,4000,formatKnots) // water speed GWBOATDATA(double,VAR,4000,formatCourse) // variation GWBOATDATA(double,DEV,4000,formatCourse) // deviation diff --git a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp index 8477ab8..7868eaf 100644 --- a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp +++ b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp @@ -500,8 +500,8 @@ private: shouldSend = updateDouble(boatData->TWD, WindDirection, msg.sourceId) && updateDouble(boatData->TWS, WindSpeed, msg.sourceId); if (WindSpeed != NMEA0183DoubleNA) boatData->MaxTws->updateMax(WindSpeed); - if(shouldSend && boatData->HDG->isValid()) { - double twa = WindDirection-boatData->HDG->getData(); + if(shouldSend && boatData->HDT->isValid()) { + double twa = WindDirection-boatData->HDT->getData(); if(twa<0) { twa+=2*M_PI; } updateDouble(boatData->TWA, twa, msg.sourceId); SetN2kWindSpeed(n2kMsg, 1, WindSpeed, twa, N2kWind_True_water); @@ -511,15 +511,15 @@ private: } void convertHDM(const SNMEA0183Msg &msg){ - double MHDG=NMEA0183DoubleNA; - if (!NMEA0183ParseHDM_nc(msg, MHDG)) + double HDM=NMEA0183DoubleNA; + if (!NMEA0183ParseHDM_nc(msg, HDM)) { LOG_DEBUG(GwLog::DEBUG, "failed to parse HDM %s", msg.line); return; } - if (! UD(MHDG)) return; + if (! UD(HDM)) return; tN2kMsg n2kMsg; - SetN2kMagneticHeading(n2kMsg,1,MHDG, + SetN2kMagneticHeading(n2kMsg,1,HDM, boatData->VAR->getDataWithDefault(N2kDoubleNA), boatData->DEV->getDataWithDefault(N2kDoubleNA) ); @@ -527,28 +527,29 @@ private: } void convertHDT(const SNMEA0183Msg &msg){ - double HDG=NMEA0183DoubleNA; - if (!NMEA0183ParseHDT_nc(msg, HDG)) + double HDT=NMEA0183DoubleNA; + if (!NMEA0183ParseHDT_nc(msg, HDT)) { LOG_DEBUG(GwLog::DEBUG, "failed to parse HDT %s", msg.line); return; } - if (! UD(HDG)) return; + if (! UD(HDT)) return; tN2kMsg n2kMsg; - SetN2kTrueHeading(n2kMsg,1,HDG); + SetN2kTrueHeading(n2kMsg,1,HDT); send(n2kMsg,msg.sourceId); } + void convertHDG(const SNMEA0183Msg &msg){ - double MHDG=NMEA0183DoubleNA; - double VAR=NMEA0183DoubleNA; + double HDM=NMEA0183DoubleNA; double DEV=NMEA0183DoubleNA; + double VAR=NMEA0183DoubleNA; if (msg.FieldCount() < 5) { LOG_DEBUG(GwLog::DEBUG, "failed to parse HDG %s", msg.line); return; } if (msg.FieldLen(0)>0){ - MHDG=formatDegToRad(atof(msg.Field(0))); + HDM=formatDegToRad(atof(msg.Field(0))); } else{ return; @@ -562,11 +563,11 @@ private: if (msg.Field(4)[0] == 'W') VAR=-VAR; } - if (! UD(MHDG)) return; + if (! UD(HDM)) return; UD(VAR); UD(DEV); tN2kMsg n2kMsg; - SetN2kMagneticHeading(n2kMsg,1,MHDG,DEV,VAR); + SetN2kMagneticHeading(n2kMsg,1,HDM,DEV,VAR); send(n2kMsg,msg.sourceId,"127250M"); } @@ -702,11 +703,11 @@ private: return; } tN2kMsg n2kMsg; - if (updateDouble(boatData->HDG,TrueHeading,msg.sourceId)){ + if (updateDouble(boatData->HDT,TrueHeading,msg.sourceId)){ SetN2kTrueHeading(n2kMsg,1,TrueHeading); send(n2kMsg,msg.sourceId); } - if(updateDouble(boatData->MHDG,MagneticHeading,msg.sourceId)){ + if(updateDouble(boatData->HDM,MagneticHeading,msg.sourceId)){ SetN2kMagneticHeading(n2kMsg,1,MagneticHeading, boatData->DEV->getDataWithDefault(N2kDoubleNA), boatData->VAR->getDataWithDefault(N2kDoubleNA) diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp index b08ac7d..390d7f1 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp @@ -185,13 +185,13 @@ private: if (N2kIsNA(Variation)){ //no variation if (ref == N2khr_magnetic){ - updateDouble(boatData->MHDG,Heading); + updateDouble(boatData->HDM,Heading); if (NMEA0183SetHDM(NMEA0183Msg,Heading,talkerId)){ SendMessage(NMEA0183Msg); } } if (ref == N2khr_true){ - updateDouble(boatData->HDG,Heading); + updateDouble(boatData->HDT,Heading); if (NMEA0183SetHDT(NMEA0183Msg,Heading,talkerId)){ SendMessage(NMEA0183Msg); } @@ -206,8 +206,8 @@ private: if (ref == N2khr_true){ MagneticHeading=Heading-Variation; } - updateDouble(boatData->MHDG,MagneticHeading); - updateDouble(boatData->HDG,Heading); + updateDouble(boatData->HDM,MagneticHeading); + updateDouble(boatData->HDT,Heading); if (!N2kIsNA(MagneticHeading)){ if (NMEA0183SetHDG(NMEA0183Msg, MagneticHeading,_Deviation, Variation,talkerId)) @@ -252,8 +252,8 @@ private: tNMEA0183Msg NMEA0183Msg; updateDouble(boatData->STW, WaterReferenced); unsigned long now = millis(); - double MagneticHeading = (boatData->HDG->isValid(now) && boatData->VAR->isValid(now)) ? boatData->HDG->getData() + boatData->VAR->getData() : NMEA0183DoubleNA; - if (NMEA0183SetVHW(NMEA0183Msg, boatData->HDG->getDataWithDefault(NMEA0183DoubleNA), MagneticHeading, WaterReferenced,talkerId)) + double MagneticHeading = (boatData->HDT->isValid(now) && boatData->VAR->isValid(now)) ? boatData->HDT->getData() + boatData->VAR->getData() : NMEA0183DoubleNA; + if (NMEA0183SetVHW(NMEA0183Msg, boatData->HDT->getDataWithDefault(NMEA0183DoubleNA), MagneticHeading, WaterReferenced,talkerId)) { SendMessage(NMEA0183Msg); } @@ -492,8 +492,8 @@ private: updateDouble(boatData->TWS, WindSpeed); setMax(boatData->MaxTws, boatData->TWS); shouldSend = true; - if (boatData->HDG->isValid()) { - double twd = WindAngle+boatData->HDG->getData(); + if (boatData->HDT->isValid()) { + double twd = WindAngle+boatData->HDT->getData(); if (twd>2*M_PI) { twd-=2*M_PI; } updateDouble(boatData->TWD, twd); } From 26d1fd40eebfc08a77e1264f032131eff7d29d16 Mon Sep 17 00:00:00 2001 From: quantenschaum Date: Thu, 22 Aug 2024 15:17:16 +0200 Subject: [PATCH 3/5] adjusted formatting --- lib/boatData/GwBoatData.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index b4df0ec..f5af8e8 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -180,13 +180,13 @@ class GwBoatData{ GWBOATDATA(double,HDT,4000,formatCourse) // true heading GWBOATDATA(double,HDM,4000,formatCourse) // magnetic heading GWBOATDATA(double,STW,4000,formatKnots) // water speed - GWBOATDATA(double,VAR,4000,formatCourse) // variation - GWBOATDATA(double,DEV,4000,formatCourse) // deviation + GWBOATDATA(double,VAR,4000,formatWind) // variation + GWBOATDATA(double,DEV,4000,formatWind) // deviation GWBOATDATA(double,AWA,4000,formatWind) // apparent wind ANGLE GWBOATDATA(double,AWS,4000,formatKnots) // apparent wind speed GWBOATDATA(double,MaxAws,0,formatKnots) GWBOATDATA(double,TWD,4000,formatCourse) // true wind DIRECTION - GWBOATDATA(double,TWA,4000,formatCourse) // true wind ANGLE + GWBOATDATA(double,TWA,4000,formatWind) // true wind ANGLE GWBOATDATA(double,TWS,4000,formatKnots) // true wind speed GWBOATDATA(double,MaxTws,0,formatKnots) GWBOATDATA(double,ROT,4000,formatRot) // rate of turn From 4ede06e33d85f15d8f8e4ed73b7e2f6ef016db31 Mon Sep 17 00:00:00 2001 From: andreas Date: Sun, 29 Sep 2024 16:27:20 +0200 Subject: [PATCH 4/5] untested: move to nmea2000 library 4.22.0, nmea0183 1.10.1 --- lib/nmea2kto0183/N2kDataToNMEA0183.cpp | 28 +++++++++++++++++--------- platformio.ini | 4 ++-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp index 26c6811..35ab4b7 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.cpp +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp @@ -657,12 +657,14 @@ private: double _Heading=N2kDoubleNA; double _ROT=N2kDoubleNA; tN2kAISNavStatus _NavStatus; + tN2kAISTransceiverInformation _AISTransceiverInformation; + uint8_t _SID; uint8_t _MessageType = 1; tNMEA0183AISMsg NMEA0183AISMsg; if (ParseN2kPGN129038(N2kMsg, SID, _Repeat, _UserID, _Latitude, _Longitude, _Accuracy, _RAIM, _Seconds, - _COG, _SOG, _Heading, _ROT, _NavStatus)) + _COG, _SOG, _Heading, _ROT, _NavStatus,_AISTransceiverInformation,_SID)) { // Debug @@ -746,12 +748,13 @@ private: tN2kGNSStype _GNSStype; tN2kAISTransceiverInformation _AISinfo; tN2kAISDTE _DTE; + uint8_t _SID; tNMEA0183AISMsg NMEA0183AISMsg; - if (ParseN2kPGN129794(N2kMsg, _MessageID, _Repeat, _UserID, _IMONumber, _Callsign, _Name, _VesselType, - _Length, _Beam, _PosRefStbd, _PosRefBow, _ETAdate, _ETAtime, _Draught, _Destination, - _AISversion, _GNSStype, _DTE, _AISinfo)) + if (ParseN2kPGN129794(N2kMsg, _MessageID, _Repeat, _UserID, _IMONumber, _Callsign, 8, _Name,21, _VesselType, + _Length, _Beam, _PosRefStbd, _PosRefBow, _ETAdate, _ETAtime, _Draught, _Destination,21, + _AISversion, _GNSStype, _DTE, _AISinfo,_SID)) { #ifdef SERIAL_PRINT_AIS_FIELDS @@ -855,9 +858,10 @@ private: bool _Display, _DSC, _Band, _Msg22, _State; tN2kAISMode _Mode; tN2kAISTransceiverInformation _AISTranceiverInformation; + uint8_t _SID; if (ParseN2kPGN129039(N2kMsg, _MessageID, _Repeat, _UserID, _Latitude, _Longitude, _Accuracy, _RAIM, - _Seconds, _COG, _SOG, _AISTranceiverInformation, _Heading, _Unit, _Display, _DSC, _Band, _Msg22, _Mode, _State)) + _Seconds, _COG, _SOG, _AISTranceiverInformation, _Heading, _Unit, _Display, _DSC, _Band, _Msg22, _Mode, _State,_SID)) { tNMEA0183AISMsg NMEA0183AISMsg; @@ -896,8 +900,10 @@ private: tN2kAISRepeat _Repeat; uint32_t _UserID; // MMSI char _Name[21]; + tN2kAISTransceiverInformation _AISInfo; + uint8_t _SID; - if (ParseN2kPGN129809(N2kMsg, _MessageID, _Repeat, _UserID, _Name)) + if (ParseN2kPGN129809(N2kMsg, _MessageID, _Repeat, _UserID, _Name,21,_AISInfo,_SID)) { tNMEA0183AISMsg NMEA0183AISMsg; @@ -923,9 +929,11 @@ private: double _Beam=N2kDoubleNA; double _PosRefStbd=N2kDoubleNA; double _PosRefBow=N2kDoubleNA; + tN2kAISTransceiverInformation _AISInfo; + uint8_t _SID; - if (ParseN2kPGN129810(N2kMsg, _MessageID, _Repeat, _UserID, _VesselType, _Vendor, _Callsign, - _Length, _Beam, _PosRefStbd, _PosRefBow, _MothershipID)) + if (ParseN2kPGN129810(N2kMsg, _MessageID, _Repeat, _UserID, _VesselType, _Vendor,4, _Callsign,8, + _Length, _Beam, _PosRefStbd, _PosRefBow, _MothershipID,_AISInfo,_SID)) { // @@ -1121,8 +1129,8 @@ private: int16_t ETADate=0; double BearingOriginToDestinationWaypoint=N2kDoubleNA; double BearingPositionToDestinationWaypoint=N2kDoubleNA; - uint8_t OriginWaypointNumber; - uint8_t DestinationWaypointNumber; + uint32_t OriginWaypointNumber; + uint32_t DestinationWaypointNumber; double DestinationLatitude=N2kDoubleNA; double DestinationLongitude=N2kDoubleNA; double WaypointClosingVelocity=N2kDoubleNA; diff --git a/platformio.ini b/platformio.ini index 0616d7f..2ed6e04 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,8 +18,8 @@ extra_configs= [basedeps] lib_deps = - ttlappalainen/NMEA2000-library @ 4.18.9 - ttlappalainen/NMEA0183 @ 1.9.1 + ttlappalainen/NMEA2000-library @ 4.22.0 + ttlappalainen/NMEA0183 @ 1.10.1 ArduinoJson @ 6.18.5 AsyncTCP-esphome @ 2.0.1 ottowinter/ESPAsyncWebServer-esphome@2.0.1 From c266bddea3001c526744bddccbe88915a032f7e2 Mon Sep 17 00:00:00 2001 From: andreas Date: Sun, 29 Sep 2024 19:56:39 +0200 Subject: [PATCH 5/5] make data store times configurable --- lib/boatData/GwBoatData.cpp | 63 ++++++++++++++-- lib/boatData/GwBoatData.h | 115 +++++++++++++++++------------- lib/xdrmappings/GwXDRMappings.cpp | 8 ++- lib/xdrmappings/GwXDRMappings.h | 10 ++- src/main.cpp | 2 +- web/config.json | 40 +++++++++++ 6 files changed, 176 insertions(+), 62 deletions(-) diff --git a/lib/boatData/GwBoatData.cpp b/lib/boatData/GwBoatData.cpp index df61ddf..f7be617 100644 --- a/lib/boatData/GwBoatData.cpp +++ b/lib/boatData/GwBoatData.cpp @@ -1,6 +1,7 @@ #include "GwBoatData.h" #include #include +#include "GWConfig.h" #define GWTYPE_DOUBLE 1 #define GWTYPE_UINT32 2 #define GWTYPE_UINT16 3 @@ -35,6 +36,23 @@ GwBoatItemBase::GwBoatItemBase(String name, String format, unsigned long invalid this->format = format; this->type = 0; this->lastUpdateSource = -1; + this->toType=TOType::user; +} +GwBoatItemBase::GwBoatItemBase(String name, String format, GwBoatItemBase::TOType toType) +{ + lastSet = 0; + this->invalidTime = INVALID_TIME; + this->toType=toType; + this->name = name; + this->format = format; + this->type = 0; + this->lastUpdateSource = -1; + this->toType=TOType::user; +} +void GwBoatItemBase::setInvalidTime(unsigned long it, bool force){ + if (toType != TOType::user || force ){ + invalidTime=it; + } } size_t GwBoatItemBase::getJsonSize() { return JSON_OBJECT_SIZE(10); } #define STRING_SIZE 40 @@ -113,6 +131,16 @@ GwBoatItem::GwBoatItem(String name, String formatInfo, unsigned long invalidT (*map)[name] = this; } } +template +GwBoatItem::GwBoatItem(String name, String formatInfo, GwBoatItemBase::TOType toType, GwBoatItemMap *map) : GwBoatItemBase(name, formatInfo, toType) +{ + T dummy; + this->type = GwBoatItemTypes::getType(dummy); + if (map) + { + (*map)[name] = this; + } +} template bool GwBoatItem::update(T nv, int source) @@ -246,14 +274,13 @@ void GwSatInfoList::houseKeeping(unsigned long ts) sats.end(), [ts, this](const GwSatInfo &info) { - return (info.timestamp + lifeTime) < ts; + return info.validTill < ts; }), sats.end()); } -void GwSatInfoList::update(GwSatInfo entry) +void GwSatInfoList::update(GwSatInfo entry, unsigned long validTill) { - unsigned long now = millis(); - entry.timestamp = now; + entry.validTill = validTill; for (auto it = sats.begin(); it != sats.end(); it++) { if (it->PRN == entry.PRN) @@ -267,7 +294,7 @@ void GwSatInfoList::update(GwSatInfo entry) sats.push_back(entry); } -GwBoatDataSatList::GwBoatDataSatList(String name, String formatInfo, unsigned long invalidTime, GwBoatItemMap *map) : GwBoatItem(name, formatInfo, invalidTime, map) {} +GwBoatDataSatList::GwBoatDataSatList(String name, String formatInfo, GwBoatItemBase::TOType toType, GwBoatItemMap *map) : GwBoatItem(name, formatInfo, toType, map) {} bool GwBoatDataSatList::update(GwSatInfo info, int source) { @@ -284,7 +311,7 @@ bool GwBoatDataSatList::update(GwSatInfo info, int source) } lastUpdateSource = source; uls(now); - data.update(info); + data.update(info,now+invalidTime); return true; } void GwBoatDataSatList::toJsonDoc(GwJsonDocument *doc, unsigned long minTime) @@ -293,9 +320,31 @@ void GwBoatDataSatList::toJsonDoc(GwJsonDocument *doc, unsigned long minTime) GwBoatItem::toJsonDoc(doc, minTime); } -GwBoatData::GwBoatData(GwLog *logger) +GwBoatData::GwBoatData(GwLog *logger, GwConfigHandler *cfg) { this->logger = logger; + for (auto &&it : values){ + unsigned long timeout=GwBoatItemBase::INVALID_TIME; + switch(it.second->getToType()){ + case GwBoatItemBase::TOType::ais: + timeout=cfg->getInt(GwConfigDefinitions::timoAis); + break; + case GwBoatItemBase::TOType::def: + timeout=cfg->getInt(GwConfigDefinitions::timoDefault); + break; + case GwBoatItemBase::TOType::lng: + timeout=cfg->getInt(GwConfigDefinitions::timoLong); + break; + case GwBoatItemBase::TOType::sensor: + timeout=cfg->getInt(GwConfigDefinitions::timoSensor); + break; + case GwBoatItemBase::TOType::keep: + timeout=0; + break; + } + it.second->setInvalidTime(timeout); + } + } GwBoatData::~GwBoatData() { diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h index f5af8e8..1c4394c 100644 --- a/lib/boatData/GwBoatData.h +++ b/lib/boatData/GwBoatData.h @@ -2,6 +2,7 @@ #define _GWBOATDATA_H #include "GwLog.h" +#include "GWConfig.h" #include #include #include @@ -15,6 +16,14 @@ class GwJsonDocument; class GwBoatItemBase{ public: + using TOType=enum{ + def=1, + ais=2, + sensor=3, + lng=4, + user=5, + keep=6 + }; class StringWriter{ uint8_t *buffer =NULL; uint8_t *wp=NULL; @@ -31,7 +40,7 @@ class GwBoatItemBase{ bool baseFilled(); void reset(); }; - static const unsigned long INVALID_TIME=60000; + static const long INVALID_TIME=60000; //the formatter names that must be known in js GWSC(formatCourse); GWSC(formatKnots); @@ -51,10 +60,11 @@ class GwBoatItemBase{ protected: int type; unsigned long lastSet=0; - unsigned long invalidTime=INVALID_TIME; + long invalidTime=INVALID_TIME; String name; String format; StringWriter writer; + TOType toType=TOType::def; void uls(unsigned long ts=0){ if (ts) lastSet=ts; else lastSet=millis(); @@ -65,7 +75,8 @@ class GwBoatItemBase{ int getCurrentType(){return type;} unsigned long getLastSet() const {return lastSet;} bool isValid(unsigned long now=0) const ; - GwBoatItemBase(String name,String format,unsigned long invalidTime=INVALID_TIME); + GwBoatItemBase(String name,String format,TOType toType); + GwBoatItemBase(String name,String format,unsigned long invalidTime); virtual ~GwBoatItemBase(){} void invalidate(){ lastSet=0; @@ -82,6 +93,8 @@ class GwBoatItemBase{ virtual double getDoubleValue()=0; String getName(){return name;} const String & getFormat() const{return format;} + virtual void setInvalidTime(unsigned long it, bool force=true); + TOType getToType(){return toType;} }; class GwBoatData; template class GwBoatItem : public GwBoatItemBase{ @@ -90,6 +103,7 @@ template class GwBoatItem : public GwBoatItemBase{ bool lastStringValid=false; public: GwBoatItem(String name,String formatInfo,unsigned long invalidTime=INVALID_TIME,GwBoatItemMap *map=NULL); + GwBoatItem(String name,String formatInfo,TOType toType,GwBoatItemMap *map=NULL); virtual ~GwBoatItem(){} bool update(T nv, int source=-1); bool updateMax(T nv,int sourceId=-1); @@ -118,14 +132,14 @@ class GwSatInfo{ uint32_t Elevation; uint32_t Azimut; uint32_t SNR; - unsigned long timestamp; + unsigned long validTill; }; class GwSatInfoList{ public: - static const unsigned long lifeTime=32000; + static const GwBoatItemBase::TOType toType=GwBoatItemBase::TOType::lng; std::vector sats; void houseKeeping(unsigned long ts=0); - void update(GwSatInfo entry); + void update(GwSatInfo entry, unsigned long validTill); int getNumSats() const{ return sats.size(); } @@ -139,7 +153,7 @@ class GwSatInfoList{ class GwBoatDataSatList : public GwBoatItem { public: - GwBoatDataSatList(String name, String formatInfo, unsigned long invalidTime = INVALID_TIME, GwBoatItemMap *map = NULL); + GwBoatDataSatList(String name, String formatInfo, GwBoatItemBase::TOType toType, GwBoatItemMap *map = NULL); bool update(GwSatInfo info, int source); virtual void toJsonDoc(GwJsonDocument *doc, unsigned long minTime); GwSatInfo *getAt(int idx){ @@ -164,56 +178,59 @@ public: virtual unsigned long getInvalidTime(){ return GwBoatItemBase::INVALID_TIME;} virtual ~GwBoatItemNameProvider() {} }; -#define GWBOATDATA(type,name,time,fmt) \ +#define GWBOATDATAT(type,name,toType,fmt) \ static constexpr const char* _##name=#name; \ - GwBoatItem *name=new GwBoatItem(#name,GwBoatItemBase::fmt,time,&values) ; -#define GWSPECBOATDATA(clazz,name,time,fmt) \ - clazz *name=new clazz(#name,GwBoatItemBase::fmt,time,&values) ; + GwBoatItem *name=new GwBoatItem(#name,GwBoatItemBase::fmt,toType,&values) ; +#define GWBOATDATA(type,name,fmt) GWBOATDATAT(type,name,GwBoatItemBase::TOType::def,fmt) +#define GWSPECBOATDATA(clazz,name,toType,fmt) \ + clazz *name=new clazz(#name,GwBoatItemBase::fmt,toType,&values) ; class GwBoatData{ + static const unsigned long DEF_TIME=4000; private: GwLog *logger; GwBoatItemBase::GwBoatItemMap values; public: - GWBOATDATA(double,COG,4000,formatCourse) // course over ground - GWBOATDATA(double,SOG,4000,formatKnots) // speed over ground - GWBOATDATA(double,HDT,4000,formatCourse) // true heading - GWBOATDATA(double,HDM,4000,formatCourse) // magnetic heading - GWBOATDATA(double,STW,4000,formatKnots) // water speed - GWBOATDATA(double,VAR,4000,formatWind) // variation - GWBOATDATA(double,DEV,4000,formatWind) // deviation - GWBOATDATA(double,AWA,4000,formatWind) // apparent wind ANGLE - GWBOATDATA(double,AWS,4000,formatKnots) // apparent wind speed - GWBOATDATA(double,MaxAws,0,formatKnots) - GWBOATDATA(double,TWD,4000,formatCourse) // true wind DIRECTION - GWBOATDATA(double,TWA,4000,formatWind) // true wind ANGLE - GWBOATDATA(double,TWS,4000,formatKnots) // true wind speed - GWBOATDATA(double,MaxTws,0,formatKnots) - GWBOATDATA(double,ROT,4000,formatRot) // rate of turn - GWBOATDATA(double,RPOS,4000,formatWind) // rudder position - GWBOATDATA(double,PRPOS,4000,formatWind) // secondary rudder position - GWBOATDATA(double,LAT,4000,formatLatitude) - GWBOATDATA(double,LON,4000,formatLongitude) - GWBOATDATA(double,ALT,4000,formatFixed0) //altitude - GWBOATDATA(double,HDOP,4000,formatDop) - GWBOATDATA(double,PDOP,4000,formatDop) - GWBOATDATA(double,VDOP,4000,formatDop) - GWBOATDATA(double,DBS,4000,formatDepth) //waterDepth (below surface) - GWBOATDATA(double,DBT,4000,formatDepth) //DepthTransducer - GWBOATDATA(double,GPST,4000,formatTime) // GPS time (seconds of day) - GWBOATDATA(uint32_t,GPSD,4000,formatDate) // GPS date (days since 1979-01-01) - GWBOATDATA(int16_t,TZ,8000,formatFixed0) - GWBOATDATA(double,WTemp,4000,kelvinToC) - GWBOATDATA(uint32_t,Log,16000,mtr2nm) - GWBOATDATA(uint32_t,TripLog,16000,mtr2nm) - GWBOATDATA(double,DTW,4000,mtr2nm) // distance to waypoint - GWBOATDATA(double,BTW,4000,formatCourse) // bearing to waypoint - GWBOATDATA(double,XTE,4000,formatXte) // cross track error - GWBOATDATA(double,WPLat,4000,formatLatitude) // waypoint latitude - GWBOATDATA(double,WPLon,4000,formatLongitude) // waypoint longitude - GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::lifeTime,formatFixed0); + GWBOATDATA(double,COG,formatCourse) // course over ground + GWBOATDATA(double,SOG,formatKnots) // speed over ground + GWBOATDATA(double,HDT,formatCourse) // true heading + GWBOATDATA(double,HDM,formatCourse) // magnetic heading + GWBOATDATA(double,STW,formatKnots) // water speed + GWBOATDATA(double,VAR,formatWind) // variation + GWBOATDATA(double,DEV,formatWind) // deviation + GWBOATDATA(double,AWA,formatWind) // apparent wind ANGLE + GWBOATDATA(double,AWS,formatKnots) // apparent wind speed + GWBOATDATAT(double,MaxAws,GwBoatItemBase::TOType::keep,formatKnots) + GWBOATDATA(double,TWD,formatCourse) // true wind DIRECTION + GWBOATDATA(double,TWA,formatWind) // true wind ANGLE + GWBOATDATA(double,TWS,formatKnots) // true wind speed + + GWBOATDATAT(double,MaxTws,GwBoatItemBase::TOType::keep,formatKnots) + GWBOATDATA(double,ROT,formatRot) // rate of turn + GWBOATDATA(double,RPOS,formatWind) // rudder position + GWBOATDATA(double,PRPOS,formatWind) // secondary rudder position + GWBOATDATA(double,LAT,formatLatitude) + GWBOATDATA(double,LON,formatLongitude) + GWBOATDATA(double,ALT,formatFixed0) //altitude + GWBOATDATA(double,HDOP,formatDop) + GWBOATDATA(double,PDOP,formatDop) + GWBOATDATA(double,VDOP,formatDop) + GWBOATDATA(double,DBS,formatDepth) //waterDepth (below surface) + GWBOATDATA(double,DBT,formatDepth) //DepthTransducer + GWBOATDATA(double,GPST,formatTime) // GPS time (seconds of day) + GWBOATDATA(uint32_t,GPSD,formatDate) // GPS date (days since 1979-01-01) + GWBOATDATAT(int16_t,TZ,GwBoatItemBase::TOType::lng,formatFixed0) + GWBOATDATA(double,WTemp,kelvinToC) + GWBOATDATAT(uint32_t,Log,GwBoatItemBase::TOType::lng,mtr2nm) + GWBOATDATAT(uint32_t,TripLog,GwBoatItemBase::TOType::lng,mtr2nm) + GWBOATDATA(double,DTW,mtr2nm) // distance to waypoint + GWBOATDATA(double,BTW,formatCourse) // bearing to waypoint + GWBOATDATA(double,XTE,formatXte) // cross track error + GWBOATDATA(double,WPLat,formatLatitude) // waypoint latitude + GWBOATDATA(double,WPLon,formatLongitude) // waypoint longitude + GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::toType,formatFixed0); public: - GwBoatData(GwLog *logger); + GwBoatData(GwLog *logger, GwConfigHandler *cfg); ~GwBoatData(); template GwBoatItem *getOrCreate(T initial,GwBoatItemNameProvider *provider); template bool update(T value,int source,GwBoatItemNameProvider *provider); diff --git a/lib/xdrmappings/GwXDRMappings.cpp b/lib/xdrmappings/GwXDRMappings.cpp index b2eb0c2..ad26bc8 100644 --- a/lib/xdrmappings/GwXDRMappings.cpp +++ b/lib/xdrmappings/GwXDRMappings.cpp @@ -355,6 +355,7 @@ void GwXDRMappings::begin() GwXDRFoundMapping GwXDRMappings::selectMapping(GwXDRMapping::MappingList *list, int instance, const char *key) { GwXDRMapping *candidate = NULL; + unsigned long invalidTime=config->getInt(GwConfigDefinitions::timoSensor); for (auto mit = list->begin(); mit != list->end(); mit++) { GwXDRMappingDef *def = (*mit)->definition; @@ -369,7 +370,7 @@ GwXDRFoundMapping GwXDRMappings::selectMapping(GwXDRMapping::MappingList *list, { LOG_DEBUG(GwLog::DEBUG + 1, "selected mapping %s for %s, i=%d", def->toString().c_str(), key, instance); - return GwXDRFoundMapping(*mit, instance); + return GwXDRFoundMapping(*mit,invalidTime, instance); } if (instance < 0) { @@ -393,7 +394,7 @@ GwXDRFoundMapping GwXDRMappings::selectMapping(GwXDRMapping::MappingList *list, { LOG_DEBUG(GwLog::DEBUG + 1, "selected mapping %s for %s, i=%d", candidate->definition->toString().c_str(), key, instance); - return GwXDRFoundMapping(candidate, instance>=0?instance:candidate->definition->instanceId); + return GwXDRFoundMapping(candidate, invalidTime,instance>=0?instance:candidate->definition->instanceId); } LOG_DEBUG(GwLog::DEBUG + 1, "no instance mapping found for key=%s, i=%d", key, instance); return GwXDRFoundMapping(); @@ -472,8 +473,9 @@ String GwXDRMappings::getXdrEntry(String mapping, double value,int instance){ } GwXDRType *type = findType(code, &typeIndex); bool first=true; + unsigned long invalidTime=config->getInt(GwConfigDefinitions::timoSensor); while (type){ - GwXDRFoundMapping found(def,type); + GwXDRFoundMapping found(def,type,invalidTime); found.instanceId=instance; if (first) first=false; else rt+=","; diff --git a/lib/xdrmappings/GwXDRMappings.h b/lib/xdrmappings/GwXDRMappings.h index 246ade5..7643bee 100644 --- a/lib/xdrmappings/GwXDRMappings.h +++ b/lib/xdrmappings/GwXDRMappings.h @@ -167,15 +167,18 @@ class GwXDRFoundMapping : public GwBoatItemNameProvider{ GwXDRType *type=NULL; int instanceId=-1; bool empty=true; - GwXDRFoundMapping(GwXDRMappingDef *definition,GwXDRType *type){ + unsigned long timeout=0; + GwXDRFoundMapping(GwXDRMappingDef *definition,GwXDRType *type, unsigned long timeout){ this->definition=definition; this->type=type; + this->timeout=timeout; empty=false; } - GwXDRFoundMapping(GwXDRMapping* mapping,int instance=0){ + GwXDRFoundMapping(GwXDRMapping* mapping,unsigned long timeout,int instance){ this->definition=mapping->definition; this->type=mapping->type; this->instanceId=instance; + this->timeout=timeout; empty=false; } GwXDRFoundMapping(){} @@ -195,6 +198,9 @@ class GwXDRFoundMapping : public GwBoatItemNameProvider{ return "formatXdr:"+type->xdrtype+":"+type->boatDataUnit; }; virtual ~GwXDRFoundMapping(){} + virtual unsigned long getInvalidTime() override{ + return timeout; + } }; //the class GwXDRMappings is not intended to be deleted diff --git a/src/main.cpp b/src/main.cpp index 599b340..17d2fa1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -138,7 +138,7 @@ bool fixedApPass=true; #endif GwWifi gwWifi(&config,&logger,fixedApPass); GwChannelList channels(&logger,&config); -GwBoatData boatData(&logger); +GwBoatData boatData(&logger,&config); GwXDRMappings xdrMappings(&logger,&config); bool sendOutN2k=true; diff --git a/web/config.json b/web/config.json index ebc5a27..7dad6ca 100644 --- a/web/config.json +++ b/web/config.json @@ -250,6 +250,46 @@ "description": "the n2k instance to be used as port rudder 0...253, -1 to disable", "category": "converter" }, + { + "name": "timeouts", + "type": "array", + "replace":[ + { + "n":"Default", + "d":"4000", + "l": "default", + "t": "NMEA" + }, + { + "n":"Sensor", + "d":"60000", + "l": "sensor", + "t": "sensor" + }, + { + "n":"Long", + "d":"32000", + "l": "long", + "t": "special NMEA" + }, + { + "n":"Ais", + "d":"120000", + "l": "ais", + "t": "ais" + } + ], + "children":[ + { + "name":"timo$n", + "label":"timeout $l", + "default": "$d", + "type": "number", + "description": "data timeouts(ms) for $t data", + "category": "converter" + } + ] + }, { "name": "usbActisense", "label": "USB mode",