From 3c4920d104ed0d7113c37a3a57be9c47a77f65ff Mon Sep 17 00:00:00 2001 From: andreas Date: Sun, 7 Nov 2021 13:12:38 +0100 Subject: [PATCH] add NMEA and NSk counter --- lib/counter/GwCounter.h | 61 ++++++++++++++ src/main.cpp | 69 +++++++++++++-- web/index.html | 182 ++++++++++++++++++++++++++++------------ 3 files changed, 252 insertions(+), 60 deletions(-) create mode 100644 lib/counter/GwCounter.h diff --git a/lib/counter/GwCounter.h b/lib/counter/GwCounter.h new file mode 100644 index 0000000..4a66aea --- /dev/null +++ b/lib/counter/GwCounter.h @@ -0,0 +1,61 @@ +#ifndef _GWCOUNTER_H +#define _GWCOUNTER_H +#include +#include "ArduinoJson.h" +template class GwCounter{ + private: + typedef std::map CounterMap; + CounterMap okCounter; + CounterMap failCounter; + unsigned long globalOk=0; + unsigned long globalFail=0; + String name; + public: + GwCounter(String name){ + this->name=name; + }; + void reset(){ + okCounter.clear(); + failCounter.clear(); + globalFail=0; + globalOk=0; + } + void add(T key){ + globalOk++; + auto it=okCounter.find(key); + if (it == okCounter.end()){ + okCounter[key]=1; + } + else{ + it->second++; + } + } + void addFail(T key){ + globalFail++; + auto it=failCounter.find(key); + if (it == failCounter.end()){ + failCounter[key]=1; + } + else{ + it->second++; + } + } + int getJsonSize(){ + return JSON_OBJECT_SIZE(4)+JSON_OBJECT_SIZE(okCounter.size()+1)+ + JSON_OBJECT_SIZE(failCounter.size()+1); + } + void toJson(JsonDocument &json){ + JsonObject jo=json.createNestedObject(name); + jo["sumOk"]=globalOk; + jo["sumFail"]=globalFail; + JsonObject jok=jo.createNestedObject("ok"); + for (auto it=okCounter.begin();it!=okCounter.end();it++){ + jok[String(it->first)]=it->second; + } + JsonObject jfail=jo.createNestedObject("fail"); + for (auto it=failCounter.begin();it!=failCounter.end();it++){ + jfail[String(it->first)]=it->second; + } + } +}; +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 043e11c..79b21ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,7 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting #include "GwApi.h" #include "GwButtons.h" #include "GwLeds.h" +#include "GwCounter.h" //NMEA message channels @@ -72,10 +73,6 @@ GwSocketServer socketServer(&config,&logger,MIN_TCP_CHANNEL_ID); GwBoatData boatData(&logger); -//counter -int numCan=0; - - int NodeAddress; // To store last Node Address Preferences preferences; // Nonvolatile storage on ESP32 - To store LastDeviceAddress @@ -88,6 +85,41 @@ void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg,int id); GwRequestQueue mainQueue(&logger,20); GwWebServer webserver(&logger,&mainQueue,80); +GwCounter countNMEA2KIn("count2Kin"); +GwCounter countNMEA2KOut("count2kout"); + +GwCounter countUSBIn("countUSBin"); +GwCounter countUSBOut("countUSBout"); +GwCounter countTCPIn("countTCPin"); +GwCounter countTCPOut("countTCPout"); +GwCounter countSerialIn("countSerialIn"); +GwCounter countSerialOut("countSerialOut"); + +void updateNMEACounter(int id,const char *msg,bool incoming,bool fail=false){ + //we rely on the msg being long enough + char key[6]; + if (msg[0] == '$') { + strncpy(key,&msg[3],3); + key[3]=0; + } + else if(msg[0] == '!'){ + strncpy(key,&msg[1],5); + key[5]=0; + } + else return; + GwCounter *counter=NULL; + if (id == USB_CHANNEL_ID) counter=incoming?&countUSBIn:&countUSBOut; + if (id == SERIAL1_CHANNEL_ID) counter=incoming?&countSerialIn:&countSerialOut; + if (id >= MIN_TCP_CHANNEL_ID) counter=incoming?&countTCPIn:&countTCPOut; + if (! counter) return; + if (fail){ + counter->addFail(key); + } + else{ + counter->add(key); + } +} + //configs that we need in main @@ -211,14 +243,30 @@ protected: virtual void processRequest() { int numPgns = nmea0183Converter->numPgns(); - DynamicJsonDocument status(256 + numPgns * 50); - status["numcan"] = numCan; + DynamicJsonDocument status(256 + + countNMEA2KIn.getJsonSize()+ + countNMEA2KOut.getJsonSize() + + countUSBIn.getJsonSize()+ + countUSBOut.getJsonSize()+ + countSerialIn.getJsonSize()+ + countSerialOut.getJsonSize()+ + countTCPIn.getJsonSize()+ + countTCPOut.getJsonSize() + ); status["version"] = VERSION; status["wifiConnected"] = gwWifi.clientConnected(); status["clientIP"] = WiFi.localIP().toString(); status["numClients"] = socketServer.numClients(); status["apIp"] = gwWifi.apIP(); - nmea0183Converter->toJson(status); + //nmea0183Converter->toJson(status); + countNMEA2KIn.toJson(status); + countNMEA2KOut.toJson(status); + countUSBIn.toJson(status); + countUSBOut.toJson(status); + countSerialIn.toJson(status); + countSerialOut.toJson(status); + countTCPIn.toJson(status); + countTCPOut.toJson(status); serializeJson(status, result); } }; @@ -444,6 +492,7 @@ void setup() { toN2KConverter= NMEA0183DataToN2K::create(&logger,&boatData,[](const tN2kMsg &msg)->bool{ logger.logDebug(GwLog::DEBUG+2,"send N2K %ld",msg.PGN); + countNMEA2KOut.add(msg.PGN); NMEA2000.SendMsg(msg); return true; }); @@ -494,7 +543,7 @@ void setup() { NMEA2000.ExtendTransmitMessages(pgns); NMEA2000.ExtendReceiveMessages(nmea0183Converter->handledPgns()); NMEA2000.SetMsgHandler([](const tN2kMsg &n2kMsg){ - numCan++; + countNMEA2KIn.add(n2kMsg.PGN); if ( sendSeasmart->asBoolean() ) { char buf[MAX_NMEA2000_MESSAGE_SEASMART_SIZE]; if ( N2kToSeasmart(n2kMsg, millis(), buf, MAX_NMEA2000_MESSAGE_SEASMART_SIZE) == 0 ) return; @@ -519,12 +568,15 @@ void setup() { void sendBufferToChannels(const char * buffer, int sourceId){ if (sendTCP->asBoolean() && checkFilter(buffer,MIN_TCP_CHANNEL_ID,false)){ socketServer.sendToClients(buffer,sourceId); + updateNMEACounter(MIN_TCP_CHANNEL_ID,buffer,false); } if (sendUsb->asBoolean() && checkFilter(buffer,USB_CHANNEL_ID,false)){ usbSerial->sendToClients(buffer,sourceId); + updateNMEACounter(USB_CHANNEL_ID,buffer,false); } if (serial1 && serCanWrite && checkFilter(buffer,SERIAL1_CHANNEL_ID,false)){ serial1->sendToClients(buffer,sourceId); + updateNMEACounter(SERIAL1_CHANNEL_ID,buffer,false); } } @@ -543,6 +595,7 @@ void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg, int sourceId) { } void handleReceivedNmeaMessage(const char *buf, int sourceId){ + updateNMEACounter(sourceId,buf,true); if (! checkFilter(buf,sourceId,true)) return; if ((sourceId == USB_CHANNEL_ID && n2kFromUSB->asBoolean())|| (sourceId >= MIN_TCP_CHANNEL_ID && n2kFromTCP->asBoolean())|| diff --git a/web/index.html b/web/index.html index 14d075a..a61da02 100644 --- a/web/index.html +++ b/web/index.html @@ -15,6 +15,12 @@ if (parent)parent.appendChild(el); return el; } + function forEl(query,callback){ + let all=document.querySelectorAll(query); + for (let i=0;iAccess Point IP --- -
- # NMEA2000 messages - --- +
+ wifi client connected + ---
- NMEA2000 details - + wifi client IP + ---
- -
- +
+ # NMEA2000 in + --- +
+
+ NMEA2000 in details + +
+ +
+ # NMEA2000 out + --- +
+
+ NMEA2000 out details + +
+
# TCP clients ---
- wifi client connected - --- + # TCP in + ---
-
- wifi client IP - --- +
+ TCP in details + +
+ +
+ # TCP out + --- +
+
+ TCP out details + +
+ +
+ # USB in + --- +
+
+ USB in details + +
+ +
+ # USB out + --- +
+
+ USB out details + +
+ +
+ # Serial in + --- +
+
+ Serial in details + +
+ +
+ # Serial out + --- +
+
+ Serial out details + +
+