send/receive zda
This commit is contained in:
parent
e1e2998a9a
commit
3cd9c5cea6
|
@ -144,6 +144,7 @@ class GwBoatData{
|
||||||
GWBOATDATA(uint32_t,Log,0,mtr2nm)
|
GWBOATDATA(uint32_t,Log,0,mtr2nm)
|
||||||
GWBOATDATA(uint32_t,TripLog,0,mtr2nm)
|
GWBOATDATA(uint32_t,TripLog,0,mtr2nm)
|
||||||
GWBOATDATA(uint32_t,DaysSince1970,4000,formatFixed0)
|
GWBOATDATA(uint32_t,DaysSince1970,4000,formatFixed0)
|
||||||
|
GWBOATDATA(int16_t,Timezone,8000,formatFixed0)
|
||||||
public:
|
public:
|
||||||
GwBoatData(GwLog *logger);
|
GwBoatData(GwLog *logger);
|
||||||
~GwBoatData();
|
~GwBoatData();
|
||||||
|
|
|
@ -133,7 +133,7 @@ private:
|
||||||
LOG_DEBUG(GwLog::DEBUG + 1, "convert RMB");
|
LOG_DEBUG(GwLog::DEBUG + 1, "convert RMB");
|
||||||
tRMB rmb;
|
tRMB rmb;
|
||||||
if (! NMEA0183ParseRMB_nc(msg,rmb)){
|
if (! NMEA0183ParseRMB_nc(msg,rmb)){
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse RMC %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse RMC %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tN2kMsg n2kMsg;
|
tN2kMsg n2kMsg;
|
||||||
|
@ -197,7 +197,7 @@ private:
|
||||||
char status;
|
char status;
|
||||||
if (!NMEA0183ParseRMC_nc(msg, SecondsSinceMidnight, status, Latitude, Longitude, COG, SOG, DaysSince1970, Variation, &DateTime))
|
if (!NMEA0183ParseRMC_nc(msg, SecondsSinceMidnight, status, Latitude, Longitude, COG, SOG, DaysSince1970, Variation, &DateTime))
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse RMC %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse RMC %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tN2kMsg n2kMsg;
|
tN2kMsg n2kMsg;
|
||||||
|
@ -235,7 +235,7 @@ private:
|
||||||
|
|
||||||
if (!NMEA0183ParseMWV_nc(msg, WindAngle, Reference,WindSpeed))
|
if (!NMEA0183ParseMWV_nc(msg, WindAngle, Reference,WindSpeed))
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse MWV %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse MWV %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tN2kMsg n2kMsg;
|
tN2kMsg n2kMsg;
|
||||||
|
@ -266,7 +266,7 @@ private:
|
||||||
double WindAngle = NMEA0183DoubleNA, WindSpeed = NMEA0183DoubleNA;
|
double WindAngle = NMEA0183DoubleNA, WindSpeed = NMEA0183DoubleNA;
|
||||||
if (msg.FieldCount() < 8 || msg.FieldLen(0) < 1)
|
if (msg.FieldCount() < 8 || msg.FieldLen(0) < 1)
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse VWR %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse VWR %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WindAngle = atof(msg.Field(0));
|
WindAngle = atof(msg.Field(0));
|
||||||
|
@ -308,7 +308,7 @@ private:
|
||||||
WindSpeed = NMEA0183DoubleNA;
|
WindSpeed = NMEA0183DoubleNA;
|
||||||
if (msg.FieldCount() < 8 )
|
if (msg.FieldCount() < 8 )
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse MWD %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse MWD %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.FieldLen(0) > 0 && msg.Field(1)[0] == 'T')
|
if (msg.FieldLen(0) > 0 && msg.Field(1)[0] == 'T')
|
||||||
|
@ -353,7 +353,7 @@ private:
|
||||||
double MagneticHeading=NMEA0183DoubleNA;
|
double MagneticHeading=NMEA0183DoubleNA;
|
||||||
if (!NMEA0183ParseHDM_nc(msg, MagneticHeading))
|
if (!NMEA0183ParseHDM_nc(msg, MagneticHeading))
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse HDM %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse HDM %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! UD(MagneticHeading)) return;
|
if (! UD(MagneticHeading)) return;
|
||||||
|
@ -369,7 +369,7 @@ private:
|
||||||
double Heading=NMEA0183DoubleNA;
|
double Heading=NMEA0183DoubleNA;
|
||||||
if (!NMEA0183ParseHDT_nc(msg, Heading))
|
if (!NMEA0183ParseHDT_nc(msg, Heading))
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse HDT %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse HDT %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! UD(Heading)) return;
|
if (! UD(Heading)) return;
|
||||||
|
@ -383,7 +383,7 @@ private:
|
||||||
double Deviation=NMEA0183DoubleNA;
|
double Deviation=NMEA0183DoubleNA;
|
||||||
if (msg.FieldCount() < 5)
|
if (msg.FieldCount() < 5)
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse HDG %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse HDG %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.FieldLen(0)>0){
|
if (msg.FieldLen(0)>0){
|
||||||
|
@ -414,7 +414,7 @@ private:
|
||||||
double Offset=NMEA0183DoubleNA;
|
double Offset=NMEA0183DoubleNA;
|
||||||
if (msg.FieldCount() < 2)
|
if (msg.FieldCount() < 2)
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse DPT %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse DPT %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.FieldLen(0)>0){
|
if (msg.FieldLen(0)>0){
|
||||||
|
@ -445,7 +445,7 @@ private:
|
||||||
double Depth=NMEA0183DoubleNA;
|
double Depth=NMEA0183DoubleNA;
|
||||||
if (msg.FieldCount() < 6)
|
if (msg.FieldCount() < 6)
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse DBK/DBS %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse DBK/DBS %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i=0;i< 3;i++){
|
for (int i=0;i< 3;i++){
|
||||||
|
@ -507,7 +507,7 @@ private:
|
||||||
double RudderPosition=NMEA0183DoubleNA;
|
double RudderPosition=NMEA0183DoubleNA;
|
||||||
if (msg.FieldCount() < 4)
|
if (msg.FieldCount() < 4)
|
||||||
{
|
{
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse RSA %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse RSA %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.FieldLen(0)>0){
|
if (msg.FieldLen(0)>0){
|
||||||
|
@ -525,7 +525,7 @@ private:
|
||||||
double MagneticHeading=NMEA0183DoubleNA;
|
double MagneticHeading=NMEA0183DoubleNA;
|
||||||
double STW=NMEA0183DoubleNA;
|
double STW=NMEA0183DoubleNA;
|
||||||
if (! NMEA0183ParseVHW_nc(msg,TrueHeading,MagneticHeading,STW)){
|
if (! NMEA0183ParseVHW_nc(msg,TrueHeading,MagneticHeading,STW)){
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse VHW %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse VHW %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! updateDouble(boatData->STW,STW,msg.sourceId)) return;
|
if (! updateDouble(boatData->STW,STW,msg.sourceId)) return;
|
||||||
|
@ -541,7 +541,7 @@ private:
|
||||||
double SOG=NMEA0183DoubleNA;
|
double SOG=NMEA0183DoubleNA;
|
||||||
double MCOG=NMEA0183DoubleNA;
|
double MCOG=NMEA0183DoubleNA;
|
||||||
if (! NMEA0183ParseVTG_nc(msg,COG,MCOG,SOG)){
|
if (! NMEA0183ParseVTG_nc(msg,COG,MCOG,SOG)){
|
||||||
logger->logDebug(GwLog::DEBUG, "failed to parse VTG %s", msg.line);
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse VTG %s", msg.line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! UD(COG)) return;
|
if (! UD(COG)) return;
|
||||||
|
@ -551,6 +551,33 @@ private:
|
||||||
SetN2kCOGSOGRapid(n2kMsg,1,N2khr_true,COG,SOG);
|
SetN2kCOGSOGRapid(n2kMsg,1,N2khr_true,COG,SOG);
|
||||||
send(n2kMsg);
|
send(n2kMsg);
|
||||||
}
|
}
|
||||||
|
void convertZDA(const SNMEA0183Msg &msg){
|
||||||
|
time_t DateTime;
|
||||||
|
long Timezone;
|
||||||
|
if (! NMEA0183ParseZDA(msg,DateTime,Timezone)){
|
||||||
|
LOG_DEBUG(GwLog::DEBUG, "failed to parse ZDA %s", msg.line);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t DaysSince1970=tNMEA0183Msg::elapsedDaysSince1970(DateTime);
|
||||||
|
tmElements_t parts;
|
||||||
|
tNMEA0183Msg::breakTime(DateTime,parts);
|
||||||
|
double SecondsSinceMidnight=parts.tm_sec+60*parts.tm_min+3600*parts.tm_hour;
|
||||||
|
if (! boatData->DaysSince1970->update(DaysSince1970,msg.sourceId)) return;
|
||||||
|
if (! boatData->SecondsSinceMidnight->update(SecondsSinceMidnight,msg.sourceId)) return;
|
||||||
|
bool timezoneValid=false;
|
||||||
|
if (msg.FieldLen(4) > 0 && msg.FieldLen(5)>0){
|
||||||
|
Timezone=Timezone/60; //N2K has offset in minutes
|
||||||
|
if (! boatData->Timezone->update(Timezone,msg.sourceId)) return;
|
||||||
|
timezoneValid=true;
|
||||||
|
}
|
||||||
|
tN2kMsg n2kMsg;
|
||||||
|
if (timezoneValid){
|
||||||
|
SetN2kLocalOffset(n2kMsg,DaysSince1970,SecondsSinceMidnight,Timezone);
|
||||||
|
send(n2kMsg);
|
||||||
|
}
|
||||||
|
SetN2kSystemTime(n2kMsg,1,DaysSince1970,SecondsSinceMidnight);
|
||||||
|
send(n2kMsg);
|
||||||
|
}
|
||||||
|
|
||||||
//shortcut for lambda converters
|
//shortcut for lambda converters
|
||||||
#define CVL [](const SNMEA0183Msg &msg, NMEA0183DataToN2KFunctions *p) -> void
|
#define CVL [](const SNMEA0183Msg &msg, NMEA0183DataToN2KFunctions *p) -> void
|
||||||
|
@ -599,7 +626,10 @@ private:
|
||||||
String(F("VHW")), &NMEA0183DataToN2KFunctions::convertVHW);
|
String(F("VHW")), &NMEA0183DataToN2KFunctions::convertVHW);
|
||||||
converters.registerConverter(
|
converters.registerConverter(
|
||||||
129026UL,
|
129026UL,
|
||||||
String(F("VTG")), &NMEA0183DataToN2KFunctions::convertVTG);
|
String(F("VTG")), &NMEA0183DataToN2KFunctions::convertVTG);
|
||||||
|
converters.registerConverter(
|
||||||
|
129033UL,126992UL,
|
||||||
|
String(F("ZDA")), &NMEA0183DataToN2KFunctions::convertZDA);
|
||||||
unsigned long *aispgns=new unsigned long[7]{129810UL,129809UL,129040UL,129039UL,129802UL,129794UL,129038UL};
|
unsigned long *aispgns=new unsigned long[7]{129810UL,129809UL,129040UL,129039UL,129802UL,129794UL,129038UL};
|
||||||
converters.registerConverter(7,&aispgns[0],
|
converters.registerConverter(7,&aispgns[0],
|
||||||
String(F("AIVDM")),&NMEA0183DataToN2KFunctions::convertAIVDX);
|
String(F("AIVDM")),&NMEA0183DataToN2KFunctions::convertAIVDX);
|
||||||
|
|
|
@ -104,6 +104,9 @@ private:
|
||||||
if (! rt){
|
if (! rt){
|
||||||
LOG_DEBUG(GwLog::DEBUG+1,"no handler for %ld",N2kMsg.PGN);
|
LOG_DEBUG(GwLog::DEBUG+1,"no handler for %ld",N2kMsg.PGN);
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
//LOG_DEBUG(GwLog::DEBUG+1,"handled %ld",N2kMsg.PGN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
virtual void toJson(JsonDocument &json)
|
virtual void toJson(JsonDocument &json)
|
||||||
{
|
{
|
||||||
|
@ -860,6 +863,60 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleSystemTime(const tN2kMsg &msg){
|
||||||
|
unsigned char sid=-1;
|
||||||
|
uint16_t DaysSince1970=N2kUInt16NA;
|
||||||
|
double SecondsSinceMidnight=N2kDoubleNA;
|
||||||
|
tN2kTimeSource TimeSource;
|
||||||
|
|
||||||
|
if (! ParseN2kSystemTime(msg,sid,DaysSince1970,SecondsSinceMidnight,TimeSource)){
|
||||||
|
LOG_DEBUG(GwLog::DEBUG,"unable to parse PGN %d",msg.PGN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateDouble(boatData->SecondsSinceMidnight,SecondsSinceMidnight);
|
||||||
|
if (DaysSince1970 != N2kUInt16NA) boatData->DaysSince1970->update(DaysSince1970,sourceId);
|
||||||
|
if (boatData->DaysSince1970->isValid() && boatData->SecondsSinceMidnight->isValid()){
|
||||||
|
tNMEA0183Msg nmeaMsg;
|
||||||
|
nmeaMsg.Init("ZDA",talkerId);
|
||||||
|
char utc[7];
|
||||||
|
double seconds=boatData->SecondsSinceMidnight->getData();
|
||||||
|
int hours=floor(seconds/3600.0);
|
||||||
|
int minutes=floor(seconds/60) - hours *60;
|
||||||
|
int sec=floor(seconds)-60*minutes-3600*hours;
|
||||||
|
snprintf(utc,7,"%02d%02d%02d",hours,minutes,sec);
|
||||||
|
nmeaMsg.AddStrField(utc);
|
||||||
|
tmElements_t timeParts;
|
||||||
|
tNMEA0183Msg::breakTime(tNMEA0183Msg::daysToTime_t(boatData->DaysSince1970->getData()),timeParts);
|
||||||
|
nmeaMsg.AddUInt32Field(tNMEA0183Msg::GetDay(timeParts));
|
||||||
|
nmeaMsg.AddUInt32Field(tNMEA0183Msg::GetMonth(timeParts));
|
||||||
|
nmeaMsg.AddUInt32Field(tNMEA0183Msg::GetYear(timeParts));
|
||||||
|
if (boatData->Timezone->isValid()){
|
||||||
|
int hours=boatData->Timezone->getData()/60;
|
||||||
|
int minutes=boatData->Timezone->getData() - 60 *hours;
|
||||||
|
nmeaMsg.AddDoubleField(hours,1,"%02.0f");
|
||||||
|
nmeaMsg.AddDoubleField(minutes,1,"%02.0f");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
nmeaMsg.AddEmptyField();
|
||||||
|
nmeaMsg.AddEmptyField();
|
||||||
|
}
|
||||||
|
SendMessage(nmeaMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleTimeOffset(const tN2kMsg &msg){
|
||||||
|
uint16_t DaysSince1970 =N2kUInt16NA;
|
||||||
|
double SecondsSinceMidnight=N2kDoubleNA;
|
||||||
|
int16_t LocalOffset=N2kInt16NA;
|
||||||
|
if (!ParseN2kLocalOffset(msg,DaysSince1970,SecondsSinceMidnight,LocalOffset)){
|
||||||
|
LOG_DEBUG(GwLog::DEBUG,"unable to parse PGN %d",msg.PGN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateDouble(boatData->SecondsSinceMidnight,SecondsSinceMidnight);
|
||||||
|
if (DaysSince1970 != N2kUInt16NA) boatData->DaysSince1970->update(DaysSince1970,sourceId);
|
||||||
|
if (LocalOffset != N2kInt16NA) boatData->Timezone->update(LocalOffset,sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void registerConverters()
|
void registerConverters()
|
||||||
{
|
{
|
||||||
|
@ -879,6 +936,8 @@ private:
|
||||||
converters.registerConverter(128275UL, &N2kToNMEA0183Functions::HandleLog);
|
converters.registerConverter(128275UL, &N2kToNMEA0183Functions::HandleLog);
|
||||||
converters.registerConverter(127245UL, &N2kToNMEA0183Functions::HandleRudder);
|
converters.registerConverter(127245UL, &N2kToNMEA0183Functions::HandleRudder);
|
||||||
converters.registerConverter(130310UL, &N2kToNMEA0183Functions::HandleWaterTemp);
|
converters.registerConverter(130310UL, &N2kToNMEA0183Functions::HandleWaterTemp);
|
||||||
|
converters.registerConverter(126992UL, &N2kToNMEA0183Functions::HandleSystemTime);
|
||||||
|
converters.registerConverter(129033UL, &N2kToNMEA0183Functions::HandleTimeOffset);
|
||||||
#define HANDLE_AIS
|
#define HANDLE_AIS
|
||||||
#ifdef HANDLE_AIS
|
#ifdef HANDLE_AIS
|
||||||
converters.registerConverter(129038UL, &N2kToNMEA0183Functions::HandleAISClassAPosReport); // AIS Class A Position Report, Message Type 1
|
converters.registerConverter(129038UL, &N2kToNMEA0183Functions::HandleAISClassAPosReport); // AIS Class A Position Report, Message Type 1
|
||||||
|
|
Loading…
Reference in New Issue