use converterlist for both directions

This commit is contained in:
andreas 2021-10-31 11:17:04 +01:00
parent f9bec3f0ba
commit 4cbd7b313d
3 changed files with 76 additions and 95 deletions

View File

@ -2,6 +2,7 @@
#define _NMEA0183CONVERTERLIST_H #define _NMEA0183CONVERTERLIST_H
#include "WString.h" #include "WString.h"
#include "ArduinoJson.h"
#include <map> #include <map>
template <class T, class Msg> template <class T, class Msg>
@ -169,5 +170,11 @@ public:
int numConverters(){ int numConverters(){
return converters.size(); return converters.size();
} }
void toJson(String prefix, JsonDocument &json){
for (auto it = converters.begin(); it != converters.end(); it++)
{
json[prefix][String(it->first)] = it->second.count;
}
}
}; };
#endif #endif

View File

@ -1,6 +1,6 @@
#include "NMEA0183DataToN2K.h" #include "NMEA0183DataToN2K.h"
#include "NMEA0183Messages.h" #include "NMEA0183Messages.h"
#include "NMEA0183ConverterList.h" #include "ConverterList.h"
NMEA0183DataToN2K::NMEA0183DataToN2K(GwLog *logger, GwBoatData *boatData,N2kSender callback) NMEA0183DataToN2K::NMEA0183DataToN2K(GwLog *logger, GwBoatData *boatData,N2kSender callback)
{ {
this->sender = callback; this->sender = callback;

View File

@ -27,6 +27,7 @@
#include "N2kDataToNMEA0183.h" #include "N2kDataToNMEA0183.h"
#include "NMEA0183AISMessages.h" #include "NMEA0183AISMessages.h"
#include "ConverterList.h"
@ -60,9 +61,9 @@ void N2kDataToNMEA0183::SendMessage(const tNMEA0183Msg &NMEA0183Msg) {
class N2kToNMEA0183Functions : public N2kDataToNMEA0183 class N2kToNMEA0183Functions : public N2kDataToNMEA0183
{ {
typedef void (N2kToNMEA0183Functions::*N2KConverter)(const tN2kMsg &N2kMsg);
private: private:
ConverterList<N2kToNMEA0183Functions,tN2kMsg> converters;
static const unsigned long RMCPeriod = 500; static const unsigned long RMCPeriod = 500;
static void setMax(GwBoatItem<double> *maxItem, GwBoatItem<double> *item) static void setMax(GwBoatItem<double> *maxItem, GwBoatItem<double> *item)
{ {
@ -138,62 +139,27 @@ private:
unsigned long LastPosSend; unsigned long LastPosSend;
unsigned long NextRMCSend; unsigned long NextRMCSend;
unsigned long lastLoopTime; unsigned long lastLoopTime;
class ConverterEntry
{
public:
unsigned long count = 0;
N2KConverter converter;
ConverterEntry(N2KConverter cv = NULL) { converter = cv; }
};
typedef std::map<long, ConverterEntry> ConverterMap;
ConverterMap converters;
/**
* register a n2k message converter
* each of the converter functions must be registered in the constructor
**/
void registerConverter(long pgn, N2KConverter converter)
{
ConverterEntry e(converter);
converters[pgn] = e;
}
virtual unsigned long *handledPgns() virtual unsigned long *handledPgns()
{ {
logger->logString("CONV: # %d handled PGNS", (int)converters.size()); logger->logString("CONV: # %d handled PGNS", converters.numConverters());
unsigned long *rt = new unsigned long[converters.size() + 1]; return converters.handledPgns();
int idx = 0;
for (ConverterMap::iterator it = converters.begin();
it != converters.end(); it++)
{
rt[idx] = it->first;
idx++;
}
rt[idx] = 0;
return rt;
} }
virtual void HandleMsg(const tN2kMsg &N2kMsg) virtual void HandleMsg(const tN2kMsg &N2kMsg)
{ {
ConverterMap::iterator it; String key=String(N2kMsg.PGN);
it = converters.find(N2kMsg.PGN); bool rt=converters.handleMessage(key,N2kMsg,this);
if (it != converters.end()) if (! rt){
{ LOG_DEBUG(GwLog::DEBUG+1,"no handler for %ld",N2kMsg.PGN);
//logger->logString("CONV: handle PGN %ld",N2kMsg.PGN);
(it->second).count++;
//call to member function - see e.g. https://isocpp.org/wiki/faq/pointers-to-members
((*this).*((it->second).converter))(N2kMsg);
return;
} }
} }
virtual void toJson(JsonDocument &json) virtual void toJson(JsonDocument &json)
{ {
for (ConverterMap::iterator it = converters.begin(); it != converters.end(); it++) converters.toJson(String(F("cnv")),json);
{
json["cnv"][String(it->first)] = it->second.count;
}
} }
virtual int numPgns() virtual int numPgns()
{ {
return converters.size(); return converters.numConverters();
} }
void SetNextRMCSend() { NextRMCSend = millis() + RMCPeriod; } void SetNextRMCSend() { NextRMCSend = millis() + RMCPeriod; }
@ -893,16 +859,8 @@ private:
return; return;
} }
public: void createBoatData()
N2kToNMEA0183Functions(GwLog *logger, GwBoatData *boatData, tNMEA2000 *NMEA2000, tSendNMEA0183MessageCallback callback, int sourceId)
: N2kDataToNMEA0183(logger, boatData, NMEA2000, callback,sourceId)
{ {
LastPosSend = 0;
lastLoopTime = 0;
NextRMCSend = millis() + RMCPeriod;
this->logger = logger;
this->boatData = boatData;
heading = boatData->getDoubleItem(F("Heading"), true, 4000, &formatCourse); heading = boatData->getDoubleItem(F("Heading"), true, 4000, &formatCourse);
latitude = boatData->getDoubleItem(F("Latitude"), true, 4000); latitude = boatData->getDoubleItem(F("Latitude"), true, 4000);
longitude = boatData->getDoubleItem(F("Longitude"), true, 4000); longitude = boatData->getDoubleItem(F("Longitude"), true, 4000);
@ -925,32 +883,48 @@ public:
tripLog = boatData->getUint32Item(F("TripLog"), true, 0, mtr2nm); tripLog = boatData->getUint32Item(F("TripLog"), true, 0, mtr2nm);
daysSince1970 = boatData->getUint32Item(F("DaysSince1970"), true, 4000); daysSince1970 = boatData->getUint32Item(F("DaysSince1970"), true, 4000);
secondsSinceMidnight = boatData->getDoubleItem(F("SecondsSinceMidnight"), true, 4000); secondsSinceMidnight = boatData->getDoubleItem(F("SecondsSinceMidnight"), true, 4000);
}
void registerConverters()
{
//register all converter functions //register all converter functions
//for each vonverter you should have a member with the N2KMsg as parameter //for each vonverter you should have a member with the N2KMsg as parameter
//and register it here //and register it here
//with this approach we easily have a list of all handled //with this approach we easily have a list of all handled
//pgns //pgns
registerConverter(127250UL, &N2kToNMEA0183Functions::HandleHeading); converters.registerConverter(127250UL, &N2kToNMEA0183Functions::HandleHeading);
registerConverter(127258UL, &N2kToNMEA0183Functions::HandleVariation); converters.registerConverter(127258UL, &N2kToNMEA0183Functions::HandleVariation);
registerConverter(128259UL, &N2kToNMEA0183Functions::HandleBoatSpeed); converters.registerConverter(128259UL, &N2kToNMEA0183Functions::HandleBoatSpeed);
registerConverter(128267UL, &N2kToNMEA0183Functions::HandleDepth); converters.registerConverter(128267UL, &N2kToNMEA0183Functions::HandleDepth);
registerConverter(129025UL, &N2kToNMEA0183Functions::HandlePosition); converters.registerConverter(129025UL, &N2kToNMEA0183Functions::HandlePosition);
registerConverter(129026UL, &N2kToNMEA0183Functions::HandleCOGSOG); converters.registerConverter(129026UL, &N2kToNMEA0183Functions::HandleCOGSOG);
registerConverter(129029UL, &N2kToNMEA0183Functions::HandleGNSS); converters.registerConverter(129029UL, &N2kToNMEA0183Functions::HandleGNSS);
registerConverter(130306UL, &N2kToNMEA0183Functions::HandleWind); converters.registerConverter(130306UL, &N2kToNMEA0183Functions::HandleWind);
registerConverter(128275UL, &N2kToNMEA0183Functions::HandleLog); converters.registerConverter(128275UL, &N2kToNMEA0183Functions::HandleLog);
registerConverter(127245UL, &N2kToNMEA0183Functions::HandleRudder); converters.registerConverter(127245UL, &N2kToNMEA0183Functions::HandleRudder);
registerConverter(130310UL, &N2kToNMEA0183Functions::HandleWaterTemp); converters.registerConverter(130310UL, &N2kToNMEA0183Functions::HandleWaterTemp);
#define HANDLE_AIS #define HANDLE_AIS
#ifdef HANDLE_AIS #ifdef HANDLE_AIS
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
registerConverter(129039UL, &N2kToNMEA0183Functions::HandleAISClassBMessage18); // AIS Class B Position Report, Message Type 18 converters.registerConverter(129039UL, &N2kToNMEA0183Functions::HandleAISClassBMessage18); // AIS Class B Position Report, Message Type 18
registerConverter(129794UL, &N2kToNMEA0183Functions::HandleAISClassAMessage5); // AIS Class A Ship Static and Voyage related data, Message Type 5 converters.registerConverter(129794UL, &N2kToNMEA0183Functions::HandleAISClassAMessage5); // AIS Class A Ship Static and Voyage related data, Message Type 5
registerConverter(129809UL, &N2kToNMEA0183Functions::HandleAISClassBMessage24A); // AIS Class B "CS" Static Data Report, Part A converters.registerConverter(129809UL, &N2kToNMEA0183Functions::HandleAISClassBMessage24A); // AIS Class B "CS" Static Data Report, Part A
registerConverter(129810UL, &N2kToNMEA0183Functions::HandleAISClassBMessage24B); // AIS Class B "CS" Static Data Report, Part B converters.registerConverter(129810UL, &N2kToNMEA0183Functions::HandleAISClassBMessage24B); // AIS Class B "CS" Static Data Report, Part B
#endif #endif
}
public:
N2kToNMEA0183Functions(GwLog *logger, GwBoatData *boatData, tNMEA2000 *NMEA2000, tSendNMEA0183MessageCallback callback, int sourceId)
: N2kDataToNMEA0183(logger, boatData, NMEA2000, callback,sourceId)
{
LastPosSend = 0;
lastLoopTime = 0;
NextRMCSend = millis() + RMCPeriod;
this->logger = logger;
this->boatData = boatData;
createBoatData();
registerConverters();
} }
virtual void loop() virtual void loop()
{ {