intermediate: handle sat status
This commit is contained in:
parent
c12ac513ba
commit
28abd16749
|
@ -61,3 +61,6 @@ double mtr2nm(double m)
|
|||
return m / 1852;
|
||||
}
|
||||
|
||||
bool convertToJson(const GwSatInfoList &si,JsonVariant &variant){
|
||||
return variant.set(si.getNumSats());
|
||||
}
|
|
@ -55,7 +55,7 @@ class GwBoatItemBase{
|
|||
};
|
||||
class GwBoatData;
|
||||
template<class T> class GwBoatItem : public GwBoatItemBase{
|
||||
private:
|
||||
protected:
|
||||
T data;
|
||||
int lastUpdateSource;
|
||||
public:
|
||||
|
@ -106,9 +106,80 @@ double formatKnots(double cv);
|
|||
uint32_t mtr2nm(uint32_t m);
|
||||
double mtr2nm(double m);
|
||||
|
||||
class GwSatInfo{
|
||||
public:
|
||||
unsigned char PRN;
|
||||
uint32_t Elevation;
|
||||
uint32_t Azimut;
|
||||
uint32_t SNR;
|
||||
unsigned long timestamp;
|
||||
};
|
||||
class GwSatInfoList{
|
||||
public:
|
||||
static const unsigned long lifeTime=32000;
|
||||
std::vector<GwSatInfo> sats;
|
||||
void houseKeeping(unsigned long ts=0){
|
||||
if (ts == 0) ts=millis();
|
||||
sats.erase(std::remove_if(
|
||||
sats.begin(),
|
||||
sats.end(),
|
||||
[ts,this](const GwSatInfo &info){
|
||||
return (info.timestamp + lifeTime) < ts;
|
||||
}
|
||||
),sats.end());
|
||||
}
|
||||
void update(GwSatInfo entry){
|
||||
unsigned long now=millis();
|
||||
entry.timestamp=now;
|
||||
for (auto it=sats.begin();it!=sats.end();it++){
|
||||
if (it->PRN == entry.PRN){
|
||||
*it=entry;
|
||||
houseKeeping();
|
||||
return;
|
||||
}
|
||||
}
|
||||
houseKeeping();
|
||||
sats.push_back(entry);
|
||||
}
|
||||
int getNumSats() const{
|
||||
return sats.size();
|
||||
}
|
||||
GwSatInfo *getAt(int idx){
|
||||
if (idx > 0 && idx < sats.size()) return &sats.at(idx);
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
bool convertToJson(const GwSatInfoList &si,JsonVariant &variant);
|
||||
class GwBoatDataSatList : public GwBoatItem<GwSatInfoList>
|
||||
{
|
||||
public:
|
||||
GwBoatDataSatList(String name, String formatInfo, unsigned long invalidTime = INVALID_TIME, GwBoatItemMap *map = NULL) : GwBoatItem<GwSatInfoList>(name, formatInfo, invalidTime, map) {}
|
||||
bool update(GwSatInfo info, 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(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#define GWBOATDATA(type,name,time,fmt) \
|
||||
GwBoatItem<type> *name=new GwBoatItem<type>(F(#name),GwBoatItemBase::fmt,time,&values) ;
|
||||
#define GWSPECBOATDATA(clazz,name,time,fmt) \
|
||||
clazz *name=new clazz(F(#name),GwBoatItemBase::fmt,time,&values) ;
|
||||
class GwBoatData{
|
||||
private:
|
||||
GwLog *logger;
|
||||
|
@ -131,6 +202,7 @@ class GwBoatData{
|
|||
GWBOATDATA(double,Deviation,4000,formatCourse)
|
||||
GWBOATDATA(double,HDOP,4000,formatDop)
|
||||
GWBOATDATA(double,PDOP,4000,formatDop)
|
||||
GWBOATDATA(double,VDOP,4000,formatDop)
|
||||
GWBOATDATA(double,RudderPosition,4000,formatCourse)
|
||||
GWBOATDATA(double,Latitude,4000,formatLatitude)
|
||||
GWBOATDATA(double,Longitude,4000,formatLongitude)
|
||||
|
@ -148,6 +220,7 @@ class GwBoatData{
|
|||
GWBOATDATA(uint32_t,TripLog,0,mtr2nm)
|
||||
GWBOATDATA(uint32_t,DaysSince1970,4000,formatFixed0)
|
||||
GWBOATDATA(int16_t,Timezone,8000,formatFixed0)
|
||||
GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::lifeTime,formatFixed0);
|
||||
public:
|
||||
GwBoatData(GwLog *logger);
|
||||
~GwBoatData();
|
||||
|
|
|
@ -612,6 +612,32 @@ private:
|
|||
DGPSAge);
|
||||
send(n2kMsg);
|
||||
}
|
||||
void convertGSA(const SNMEA0183Msg &msg){
|
||||
if (msg.FieldCount() < 17)
|
||||
{
|
||||
LOG_DEBUG(GwLog::DEBUG, "failed to parse GSA %s", msg.line);
|
||||
return;
|
||||
}
|
||||
int fixMode=atoi(msg.Field(1));
|
||||
|
||||
tN2kMsg n2kMsg;
|
||||
tN2kGNSSDOPmode mode=N2kGNSSdm_Unavailable;
|
||||
if (fixMode >= 0 && fixMode <=3) mode=(tN2kGNSSDOPmode)fixMode;
|
||||
tN2kGNSSDOPmode rmode=mode;
|
||||
if (msg.Field(0)[0] == 'A') rmode=N2kGNSSdm_Auto;
|
||||
double HDOP=N2kDoubleNA;
|
||||
double VDOP=N2kDoubleNA;
|
||||
if (msg.FieldLen(15)> 0){
|
||||
HDOP=atof(msg.Field(15));
|
||||
if (!updateDouble(boatData->HDOP,HDOP,msg.sourceId)) return;
|
||||
}
|
||||
if (msg.FieldLen(16)> 0){
|
||||
VDOP=atof(msg.Field(16));
|
||||
if (!updateDouble(boatData->VDOP,VDOP,msg.sourceId)) return;
|
||||
}
|
||||
SetN2kGNSSDOPData(n2kMsg,1,rmode,mode,HDOP,VDOP,N2kDoubleNA);
|
||||
send(n2kMsg);
|
||||
}
|
||||
|
||||
//shortcut for lambda converters
|
||||
#define CVL [](const SNMEA0183Msg &msg, NMEA0183DataToN2KFunctions *p) -> void
|
||||
|
@ -667,6 +693,9 @@ private:
|
|||
converters.registerConverter(
|
||||
129029UL,
|
||||
String(F("GGA")), &NMEA0183DataToN2KFunctions::convertGGA);
|
||||
converters.registerConverter(
|
||||
129539UL,
|
||||
String(F("GSA")), &NMEA0183DataToN2KFunctions::convertGSA);
|
||||
unsigned long *aispgns=new unsigned long[7]{129810UL,129809UL,129040UL,129039UL,129802UL,129794UL,129038UL};
|
||||
converters.registerConverter(7,&aispgns[0],
|
||||
String(F("AIVDM")),&NMEA0183DataToN2KFunctions::convertAIVDX);
|
||||
|
|
|
@ -323,6 +323,37 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
void HandleDop(const tN2kMsg &msg){
|
||||
double HDOP=N2kDoubleNA;
|
||||
double VDOP=N2kDoubleNA;
|
||||
double TDOP;
|
||||
tN2kGNSSDOPmode DesiredMode;
|
||||
tN2kGNSSDOPmode ActualMode;
|
||||
unsigned char SID;
|
||||
if (ParseN2kGNSSDOPData(msg,SID, DesiredMode, ActualMode,
|
||||
HDOP, VDOP, TDOP)){
|
||||
updateDouble(boatData->HDOP,HDOP);
|
||||
updateDouble(boatData->VDOP,VDOP);
|
||||
}
|
||||
}
|
||||
void HandleSats(const tN2kMsg &msg){
|
||||
unsigned char SID;
|
||||
tN2kRangeResidualMode Mode;
|
||||
uint8_t NumberOfSVs;
|
||||
tSatelliteInfo info;
|
||||
if (ParseN2kPGNSatellitesInView(msg,SID,Mode,NumberOfSVs)){
|
||||
for (int i=0;i<NumberOfSVs;i++){
|
||||
if (ParseN2kPGNSatellitesInView(msg,i,info)){
|
||||
GwSatInfo satInfo;
|
||||
satInfo.PRN=info.PRN;
|
||||
satInfo.Elevation=info.Elevation;
|
||||
satInfo.Azimut=info.Azimuth;
|
||||
satInfo.SNR=info.SNR;
|
||||
if (! boatData->SatInfo->update(satInfo,sourceId)) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void HandleWind(const tN2kMsg &N2kMsg)
|
||||
|
@ -948,6 +979,8 @@ private:
|
|||
converters.registerConverter(130310UL, &N2kToNMEA0183Functions::HandleWaterTemp);
|
||||
converters.registerConverter(126992UL, &N2kToNMEA0183Functions::HandleSystemTime);
|
||||
converters.registerConverter(129033UL, &N2kToNMEA0183Functions::HandleTimeOffset);
|
||||
converters.registerConverter(129539UL, &N2kToNMEA0183Functions::HandleDop);
|
||||
converters.registerConverter(129540UL, &N2kToNMEA0183Functions::HandleSats);
|
||||
#define HANDLE_AIS
|
||||
#ifdef HANDLE_AIS
|
||||
converters.registerConverter(129038UL, &N2kToNMEA0183Functions::HandleAISClassAPosReport); // AIS Class A Position Report, Message Type 1
|
||||
|
|
Loading…
Reference in New Issue