1
0
mirror of https://github.com/thooge/esp32-nmea2000-obp60.git synced 2025-12-13 05:53:06 +01:00

Merge branch 'wellenvogel:master' into master

This commit is contained in:
norbert-walter
2021-12-21 11:58:37 +01:00
committed by GitHub
29 changed files with 5105 additions and 132 deletions

View File

@@ -15,6 +15,7 @@ class GwApi{
public:
double value=0;
bool valid=false;
bool changed=false; //will be set by getBoatDataValues
BoatValue(){}
BoatValue(const String &n):name(n){
}

18
lib/appinfo/GwAppInfo.h Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#define GWSTR(x) #x
#define GWSTRINGIFY(x) GWSTR(x)
#ifdef GWRELEASEVERSION
#define VERSION GWSTRINGIFY(GWRELEASEVERSION)
#define LOGLEVEL GwLog::ERROR
#else
#ifdef GWDEVVERSION
#define VERSION GWSTRINGIFY(GWDEVVERSION)
#define LOGLEVEL GwLog::DEBUG
#endif
#ifndef VERSION
#define VERSION "0.9.9"
#define LOGLEVEL GwLog::DEBUG
#endif
#endif
#define FIRMWARE_TYPE GWSTRINGIFY(PIO_ENV_BUILD)

View File

@@ -193,7 +193,7 @@ class GwBoatData{
GWBOATDATA(double,Altitude,4000,formatFixed0)
GWBOATDATA(double,WaterDepth,4000,formatDepth)
GWBOATDATA(double,DepthTransducer,4000,formatDepth)
GWBOATDATA(double,SecondsSinceMidnight,4000,formatTime)
GWBOATDATA(double,GpsTime,4000,formatTime)
GWBOATDATA(double,WaterTemperature,4000,kelvinToC)
GWBOATDATA(double,XTE,4000,formatXte)
GWBOATDATA(double,DTW,4000,mtr2nm)
@@ -202,7 +202,7 @@ class GwBoatData{
GWBOATDATA(double,WPLongitude,4000,formatLongitude)
GWBOATDATA(uint32_t,Log,16000,mtr2nm)
GWBOATDATA(uint32_t,TripLog,16000,mtr2nm)
GWBOATDATA(uint32_t,DaysSince1970,4000,formatDate)
GWBOATDATA(uint32_t,GpsDate,4000,formatDate)
GWBOATDATA(int16_t,Timezone,8000,formatFixed0)
GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::lifeTime,formatFixed0);
public:

View File

@@ -39,7 +39,7 @@ String GwConfigHandler::toJson() const{
}
}
serializeJson(jdoc,rt);
logger->logString("configJson: %s",rt.c_str());
LOG_DEBUG(GwLog::DEBUG,"configJson: %s",rt.c_str());
return rt;
}
@@ -71,11 +71,11 @@ bool GwConfigHandler::saveConfig(){
if (it != changedValues.end()){
val=it->second;
}
logger->logString("saving %s=%s",configs[i]->getName().c_str(),val.c_str());
LOG_DEBUG(GwLog::LOG,"saving %s=%s",configs[i]->getName().c_str(),val.c_str());
prefs.putString(configs[i]->getName().c_str(),val);
}
prefs.end();
logger->logString("saved config");
LOG_DEBUG(GwLog::LOG,"saved config");
return true;
}
@@ -92,7 +92,7 @@ bool GwConfigHandler::updateValue(String name, String value){
return true;
}
bool GwConfigHandler::reset(bool save){
logger->logString("reset config");
LOG_DEBUG(GwLog::LOG,"reset config");
for (int i=0;i<getNumConfig();i++){
changedValues[configs[i]->getName()]=configs[i]->getDefault();
}

View File

@@ -88,8 +88,6 @@ void exampleTask(GwApi *api){
GwApi::BoatValue *latitude=new GwApi::BoatValue(F("Latitude"));
GwApi::BoatValue *testValue=new GwApi::BoatValue(boatItemName);
GwApi::BoatValue *valueList[]={longitude,latitude,testValue};
double lastTestValue=0;
bool lastTestValueValid=false;
while(true){
delay(1000);
/*
@@ -155,16 +153,13 @@ void exampleTask(GwApi *api){
}
}
if (testValue->valid){
if (! lastTestValueValid || lastTestValue != testValue->value){
if (testValue->changed){
LOG_DEBUG(GwLog::LOG,"%s new value %s",testValue->getName().c_str(),formatValue(testValue).c_str());
lastTestValueValid=true;
lastTestValue=testValue->value;
}
}
else{
if (lastTestValueValid){
if (testValue->changed){
LOG_DEBUG(GwLog::LOG,"%s now invalid",testValue->getName().c_str());
lastTestValueValid=false;
}
}

View File

@@ -365,23 +365,23 @@ private:
}
void convertRMC(const SNMEA0183Msg &msg)
{
double SecondsSinceMidnight=0, Latitude=0, Longitude=0, COG=0, SOG=0, Variation=0;
unsigned long DaysSince1970=0;
double GpsTime=0, Latitude=0, Longitude=0, COG=0, SOG=0, Variation=0;
unsigned long GpsDate=0;
time_t DateTime;
char status;
if (!NMEA0183ParseRMC_nc(msg, SecondsSinceMidnight, status, Latitude, Longitude, COG, SOG, DaysSince1970, Variation, &DateTime))
if (!NMEA0183ParseRMC_nc(msg, GpsTime, status, Latitude, Longitude, COG, SOG, GpsDate, Variation, &DateTime))
{
LOG_DEBUG(GwLog::DEBUG, "failed to parse RMC %s", msg.line);
return;
}
tN2kMsg n2kMsg;
if (
UD(SecondsSinceMidnight) &&
UI(DaysSince1970)
UD(GpsTime) &&
UI(GpsDate)
)
{
SetN2kSystemTime(n2kMsg, 1, DaysSince1970, SecondsSinceMidnight);
SetN2kSystemTime(n2kMsg, 1, GpsDate, GpsTime);
send(n2kMsg);
}
if (UD(Latitude) &&
@@ -395,7 +395,7 @@ private:
}
if (UD(Variation)){
SetN2kMagneticVariation(n2kMsg,1,N2kmagvar_Calc,
getUint32(boatData->DaysSince1970), Variation);
getUint32(boatData->GpsDate), Variation);
send(n2kMsg);
}
@@ -739,9 +739,9 @@ private:
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;
double GpsTime=parts.tm_sec+60*parts.tm_min+3600*parts.tm_hour;
if (! boatData->GpsDate->update(DaysSince1970,msg.sourceId)) return;
if (! boatData->GpsTime->update(GpsTime,msg.sourceId)) return;
bool timezoneValid=false;
if (msg.FieldLen(4) > 0 && msg.FieldLen(5)>0){
Timezone=Timezone/60; //N2K has offset in minutes
@@ -750,10 +750,10 @@ private:
}
tN2kMsg n2kMsg;
if (timezoneValid){
SetN2kLocalOffset(n2kMsg,DaysSince1970,SecondsSinceMidnight,Timezone);
SetN2kLocalOffset(n2kMsg,DaysSince1970,GpsTime,Timezone);
send(n2kMsg);
}
SetN2kSystemTime(n2kMsg,1,DaysSince1970,SecondsSinceMidnight);
SetN2kSystemTime(n2kMsg,1,DaysSince1970,GpsTime);
send(n2kMsg);
}
void convertGGA(const SNMEA0183Msg &msg){
@@ -773,16 +773,16 @@ private:
LOG_DEBUG(GwLog::DEBUG, "failed to parse GGA %s", msg.line);
return;
}
if (! updateDouble(boatData->SecondsSinceMidnight,GPSTime,msg.sourceId)) return;
if (! updateDouble(boatData->GpsTime,GPSTime,msg.sourceId)) return;
if (! updateDouble(boatData->Latitude,Latitude,msg.sourceId)) return;
if (! updateDouble(boatData->Longitude,Longitude,msg.sourceId)) return;
if (! updateDouble(boatData->Altitude,Altitude,msg.sourceId)) return;
if (! updateDouble(boatData->HDOP,HDOP,msg.sourceId)) return;
if (! boatData->DaysSince1970->isValid()) return;
if (! boatData->GpsDate->isValid()) return;
tN2kMsg n2kMsg;
tN2kGNSSmethod method=N2kGNSSm_noGNSS;
if (GPSQualityIndicator <=5 ) method= (tN2kGNSSmethod)GPSQualityIndicator;
SetN2kGNSS(n2kMsg,1, boatData->DaysSince1970->getData(),
SetN2kGNSS(n2kMsg,1, boatData->GpsDate->getData(),
GPSTime, Latitude, Longitude, Altitude,
N2kGNSSt_GPS, method,
SatelliteCount, HDOP, boatData->PDOP->getDataWithDefault(N2kDoubleNA), 0,
@@ -882,7 +882,7 @@ private:
if (GLL.status != 'A') return;
if (! updateDouble(boatData->Latitude,GLL.latitude,msg.sourceId)) return;
if (! updateDouble(boatData->Longitude,GLL.longitude,msg.sourceId)) return;
if (! updateDouble(boatData->SecondsSinceMidnight,GLL.GPSTime,msg.sourceId)) return;
if (! updateDouble(boatData->GpsTime,GLL.GPSTime,msg.sourceId)) return;
tN2kMsg n2kMsg;
SetN2kLatLonRapid(n2kMsg,GLL.latitude,GLL.longitude);
send(n2kMsg);

View File

@@ -142,7 +142,7 @@ private:
virtual unsigned long *handledPgns()
{
logger->logString("CONV: # %d handled PGNS", converters.numConverters());
LOG_DEBUG(GwLog::LOG,"CONV: # %d handled PGNS", converters.numConverters());
return converters.handledPgns();
}
virtual String handledKeys(){
@@ -242,7 +242,7 @@ private:
ParseN2kMagneticVariation(N2kMsg, SID, Source, DaysSince1970, Variation);
updateDouble(boatData->Variation, Variation);
if (DaysSince1970 != N2kUInt16NA && DaysSince1970 != 0)
boatData->DaysSince1970->update(DaysSince1970,sourceId);
boatData->GpsDate->update(DaysSince1970,sourceId);
}
//*****************************************************************************
@@ -377,23 +377,23 @@ private:
double Longitude;
double Altitude;
uint16_t DaysSince1970;
double SecondsSinceMidnight;
if (ParseN2kGNSS(N2kMsg, SID, DaysSince1970, SecondsSinceMidnight, Latitude, Longitude, Altitude, GNSStype, GNSSmethod,
double GpsTime;
if (ParseN2kGNSS(N2kMsg, SID, DaysSince1970, GpsTime, Latitude, Longitude, Altitude, GNSStype, GNSSmethod,
nSatellites, HDOP, PDOP, GeoidalSeparation,
nReferenceStations, ReferenceStationType, ReferenceSationID, AgeOfCorrection))
{
updateDouble(boatData->Latitude, Latitude);
updateDouble(boatData->Longitude, Longitude);
updateDouble(boatData->Altitude, Altitude);
updateDouble(boatData->SecondsSinceMidnight, SecondsSinceMidnight);
updateDouble(boatData->GpsTime, GpsTime);
updateDouble(boatData->HDOP,HDOP);
updateDouble(boatData->PDOP,PDOP);
if (DaysSince1970 != N2kUInt16NA && DaysSince1970 != 0)
boatData->DaysSince1970->update(DaysSince1970,sourceId);
boatData->GpsDate->update(DaysSince1970,sourceId);
int quality=0;
if ((int)GNSSmethod <= 5) quality=(int)GNSSmethod;
tNMEA0183AISMsg nmeaMsg;
if (NMEA0183SetGGA(nmeaMsg,SecondsSinceMidnight,Latitude,Longitude,
if (NMEA0183SetGGA(nmeaMsg,GpsTime,Latitude,Longitude,
quality,nSatellites,HDOP,Altitude,GeoidalSeparation,AgeOfCorrection,
ReferenceSationID,talkerId)){
SendMessage(nmeaMsg);
@@ -555,12 +555,12 @@ private:
tNMEA0183Msg NMEA0183Msg;
if (NMEA0183SetRMC(NMEA0183Msg,
boatData->SecondsSinceMidnight->getDataWithDefault(NMEA0183DoubleNA),
boatData->GpsTime->getDataWithDefault(NMEA0183DoubleNA),
boatData->Latitude->getDataWithDefault(NMEA0183DoubleNA),
boatData->Longitude->getDataWithDefault(NMEA0183DoubleNA),
boatData->COG->getDataWithDefault(NMEA0183DoubleNA),
boatData->SOG->getDataWithDefault(NMEA0183DoubleNA),
boatData->DaysSince1970->getDataWithDefault(NMEA0183UInt32NA),
boatData->GpsDate->getDataWithDefault(NMEA0183UInt32NA),
boatData->Variation->getDataWithDefault(NMEA0183DoubleNA),
talkerId))
{
@@ -574,16 +574,16 @@ private:
void HandleLog(const tN2kMsg &N2kMsg)
{
uint16_t DaysSince1970;
double SecondsSinceMidnight;
double GpsTime;
uint32_t Log, TripLog;
if (ParseN2kDistanceLog(N2kMsg, DaysSince1970, SecondsSinceMidnight, Log, TripLog))
if (ParseN2kDistanceLog(N2kMsg, DaysSince1970, GpsTime, Log, TripLog))
{
if (Log != N2kUInt32NA)
boatData->Log->update(Log,sourceId);
if (TripLog != N2kUInt32NA)
boatData->TripLog->update(TripLog,sourceId);
if (DaysSince1970 != N2kUInt16NA && DaysSince1970 != 0)
boatData->DaysSince1970->update(DaysSince1970,sourceId);
boatData->GpsDate->update(DaysSince1970,sourceId);
tNMEA0183Msg NMEA0183Msg;
if (!NMEA0183Msg.Init("VLW", talkerId))
@@ -996,27 +996,27 @@ private:
void HandleSystemTime(const tN2kMsg &msg){
unsigned char sid=-1;
uint16_t DaysSince1970=N2kUInt16NA;
double SecondsSinceMidnight=N2kDoubleNA;
double GpsTime=N2kDoubleNA;
tN2kTimeSource TimeSource;
if (! ParseN2kSystemTime(msg,sid,DaysSince1970,SecondsSinceMidnight,TimeSource)){
if (! ParseN2kSystemTime(msg,sid,DaysSince1970,GpsTime,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()){
updateDouble(boatData->GpsTime,GpsTime);
if (DaysSince1970 != N2kUInt16NA) boatData->GpsDate->update(DaysSince1970,sourceId);
if (boatData->GpsDate->isValid() && boatData->GpsTime->isValid()){
tNMEA0183Msg nmeaMsg;
nmeaMsg.Init("ZDA",talkerId);
char utc[7];
double seconds=boatData->SecondsSinceMidnight->getData();
double seconds=boatData->GpsTime->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);
tNMEA0183Msg::breakTime(tNMEA0183Msg::daysToTime_t(boatData->GpsDate->getData()),timeParts);
nmeaMsg.AddUInt32Field(tNMEA0183Msg::GetDay(timeParts));
nmeaMsg.AddUInt32Field(tNMEA0183Msg::GetMonth(timeParts));
nmeaMsg.AddUInt32Field(tNMEA0183Msg::GetYear(timeParts));
@@ -1036,14 +1036,14 @@ private:
void HandleTimeOffset(const tN2kMsg &msg){
uint16_t DaysSince1970 =N2kUInt16NA;
double SecondsSinceMidnight=N2kDoubleNA;
double GpsTime=N2kDoubleNA;
int16_t LocalOffset=N2kInt16NA;
if (!ParseN2kLocalOffset(msg,DaysSince1970,SecondsSinceMidnight,LocalOffset)){
if (!ParseN2kLocalOffset(msg,DaysSince1970,GpsTime,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);
updateDouble(boatData->GpsTime,GpsTime);
if (DaysSince1970 != N2kUInt16NA) boatData->GpsDate->update(DaysSince1970,sourceId);
if (LocalOffset != N2kInt16NA) boatData->Timezone->update(LocalOffset,sourceId);
}
void HandleROT(const tN2kMsg &msg){

View File

@@ -163,7 +163,7 @@ void GwSocketServer::begin(){
}
server=new WiFiServer(config->getInt(config->serverPort),maxClients+1);
server->begin();
logger->logString("Socket server created, port=%d",
LOG_DEBUG(GwLog::LOG,"Socket server created, port=%d",
config->getInt(config->serverPort));
MDNS.addService("_nmea-0183","_tcp",config->getInt(config->serverPort));
@@ -175,7 +175,7 @@ void GwSocketServer::loop(bool handleRead,bool handleWrite)
if (client)
{
logger->logString("new client connected from %s",
LOG_DEBUG(GwLog::LOG,"new client connected from %s",
client.remoteIP().toString().c_str());
fcntl(client.fd(), F_SETFL, O_NONBLOCK);
bool canHandle = false;
@@ -184,7 +184,7 @@ void GwSocketServer::loop(bool handleRead,bool handleWrite)
if (!clients[i]->hasClient())
{
clients[i]->setClient(wiFiClientPtr(new WiFiClient(client)));
logger->logString("set client as number %d", i);
LOG_DEBUG(GwLog::LOG,"set client as number %d", i);
canHandle = true;
break;
}
@@ -219,7 +219,7 @@ void GwSocketServer::loop(bool handleRead,bool handleWrite)
if (!client->client->connected())
{
logger->logString("client %d disconnect %s", i, client->remoteIp.c_str());
LOG_DEBUG(GwLog::LOG,"client %d disconnect %s", i, client->remoteIp.c_str());
client->client->stop();
client->setClient(NULL);
}

View File

@@ -11,7 +11,7 @@ GwWifi::GwWifi(const GwConfigHandler *config,GwLog *log, bool fixedApPass){
this->fixedApPass=fixedApPass;
}
void GwWifi::setup(){
logger->logString("Wifi setup");
LOG_DEBUG(GwLog::LOG,"Wifi setup");
IPAddress AP_local_ip(192, 168, 15, 1); // Static address for AP
IPAddress AP_gateway(192, 168, 15, 1);
@@ -26,7 +26,7 @@ void GwWifi::setup(){
}
delay(100);
WiFi.softAPConfig(AP_local_ip, AP_gateway, AP_subnet);
logger->logString("WifiAP created: ssid=%s,adress=%s",
LOG_DEBUG(GwLog::LOG,"WifiAP created: ssid=%s,adress=%s",
ssid,
WiFi.softAPIP().toString().c_str()
);
@@ -34,7 +34,7 @@ void GwWifi::setup(){
lastApAccess=millis();
apShutdownTime=config->getConfigItem(config->stopApTime)->asInt() * 60;
if (apShutdownTime < 120 && apShutdownTime != 0) apShutdownTime=120; //min 2 minutes
logger->logString("GWWIFI: AP auto shutdown %s (%ds)",apShutdownTime> 0?"enabled":"disabled",apShutdownTime);
LOG_DEBUG(GwLog::LOG,"GWWIFI: AP auto shutdown %s (%ds)",apShutdownTime> 0?"enabled":"disabled",apShutdownTime);
apShutdownTime=apShutdownTime*1000; //ms
clientIsConnected=false;
connectInternal();
@@ -42,7 +42,7 @@ void GwWifi::setup(){
bool GwWifi::connectInternal(){
if (wifiClient->asBoolean()){
clientIsConnected=false;
logger->logString("creating wifiClient ssid=%s",wifiSSID->asString().c_str());
LOG_DEBUG(GwLog::LOG,"creating wifiClient ssid=%s",wifiSSID->asString().c_str());
wl_status_t rt=WiFi.begin(wifiSSID->asCString(),wifiPass->asCString());
LOG_DEBUG(GwLog::LOG,"wifiClient connect returns %d",(int)rt);
lastConnectStart=millis();
@@ -76,7 +76,7 @@ void GwWifi::loop(){
lastApAccess=millis();
}
if ((lastApAccess + apShutdownTime) < millis()){
logger->logString("GWWIFI: shutdown AP");
LOG_DEBUG(GwLog::LOG,"GWWIFI: shutdown AP");
WiFi.softAPdisconnect(true);
apActive=false;
}