From 63eb31781697f614b901baf9b20298a33305d82f Mon Sep 17 00:00:00 2001 From: andreas Date: Thu, 21 Oct 2021 18:10:25 +0200 Subject: [PATCH] add extended nmea2k status --- lib/nmea2kto0183/N2kDataToNMEA0183.h | 2 + lib/nmea2kto0183/N2kToNMEA0183Functions.h | 48 ++++++++++++------ src/main.cpp | 6 ++- web/index.html | 59 +++++++++++++++++++++-- 4 files changed, 94 insertions(+), 21 deletions(-) diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.h b/lib/nmea2kto0183/N2kDataToNMEA0183.h index 445f2e5..3b11e4b 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.h +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.h @@ -57,5 +57,7 @@ public: virtual void loop(); virtual ~N2kDataToNMEA0183(){} virtual const unsigned long* handledPgns()=0; + virtual int numPgns()=0; + virtual void toJson(JsonDocument &json)=0; }; #endif \ No newline at end of file diff --git a/lib/nmea2kto0183/N2kToNMEA0183Functions.h b/lib/nmea2kto0183/N2kToNMEA0183Functions.h index 8e2f26f..c998b75 100644 --- a/lib/nmea2kto0183/N2kToNMEA0183Functions.h +++ b/lib/nmea2kto0183/N2kToNMEA0183Functions.h @@ -90,21 +90,28 @@ private: unsigned long LastPosSend; unsigned long NextRMCSend; unsigned long lastLoopTime; - - std::map converters; + class ConverterEntry{ + public: + unsigned long count=0; + N2KConverter converter; + ConverterEntry(N2KConverter cv=NULL){converter=cv;} + }; + typedef std::map 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){ - converters[pgn]=converter; + ConverterEntry e(converter); + converters[pgn]=e; } virtual const unsigned long * handledPgns(){ logger->logString("CONV: # %d handled PGNS",(int)converters.size()); unsigned long *rt=new unsigned long[converters.size()+1]; int idx=0; - for (std::map::iterator it=converters.begin(); + for (ConverterMap::iterator it=converters.begin(); it != converters.end();it++){ rt[idx]=it->first; idx++; @@ -112,6 +119,26 @@ private: rt[idx]=0; return rt; } + virtual void HandleMsg(const tN2kMsg &N2kMsg) + { + ConverterMap::iterator it; + it = converters.find(N2kMsg.PGN); + if (it != converters.end()){ + //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){ + for (ConverterMap::iterator it=converters.begin();it != converters.end();it++){ + json["cnv"][String(it->first)]=it->second.count; + } + } + virtual int numPgns(){ + return converters.size(); + } void SetNextRMCSend() { NextRMCSend = millis() + RMCPeriod; } //*************** the converters *********************** @@ -488,7 +515,7 @@ public: //and register it here //with this approach we easily have a list of all handled //pgns - registerConverter(127250UL,&N2kToNMEA0183Functions::HandleMsg); + registerConverter(127250UL,&N2kToNMEA0183Functions::HandleHeading); registerConverter(127258UL,&N2kToNMEA0183Functions::HandleVariation); registerConverter(128259UL,&N2kToNMEA0183Functions::HandleBoatSpeed); registerConverter(128267UL,&N2kToNMEA0183Functions::HandleDepth); @@ -509,16 +536,5 @@ public: lastLoopTime = now; SendRMC(); } - virtual void HandleMsg(const tN2kMsg &N2kMsg) - { - std::map::iterator it; - it = converters.find(N2kMsg.PGN); - if (it != converters.end()){ - //logger->logString("CONV: handle PGN %ld",N2kMsg.PGN); - //call to member function - see e.g. https://isocpp.org/wiki/faq/pointers-to-members - ((*this).*(it->second))(N2kMsg); - return; - } - } }; #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 30a68a3..5771b73 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,7 +12,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#define VERSION "0.0.5" +#define VERSION "0.0.7" #include "GwHardware.h" #define LOG_SERIAL true @@ -101,12 +101,14 @@ void js_reset() // Wenn "http:///gauge.min.js" aufgerufen wurde void js_status(){ - StaticJsonDocument<256> status; + int numPgns=nmea0183Converter->numPgns(); + DynamicJsonDocument status(256*numPgns*30); status["numcan"]=numCan; status["version"]=VERSION; status["wifiConnected"]=gwWifi.clientConnected(); status["clientIP"]=WiFi.localIP().toString(); status["numClients"]=socketServer.numClients(); + nmea0183Converter->toJson(status); String buf; serializeJson(status,buf); webserver.send(200,F("application/json"),buf); diff --git a/web/index.html b/web/index.html index 2b75508..18587e8 100644 --- a/web/index.html +++ b/web/index.html @@ -31,8 +31,13 @@ getJson('/api/status') .then(function(jsonData){ for (let k in jsonData){ - let el=document.getElementById(k); - if (el) el.textContent=jsonData[k]; + if (k == 'cnv'){ + updateCanDetails(jsonData[k]); + } + else{ + let el=document.getElementById(k); + if (el) el.textContent=jsonData[k]; + } } lastUpdate=(new Date()).getTime(); }) @@ -72,6 +77,36 @@ alertRestart(); }) } + function showCanDetails(on){ + let el=document.getElementById('canDetails'); + if (!el) return; + if (on) el.classList.add('visible'); + else(el.classList).remove('visible'); + } + function updateCanDetails(details){ + let frame=document.getElementById('canDetails'); + if (! frame) return; + for (let k in details){ + let el=frame.querySelector("[data-id=\""+k+"\"] "); + if (!el){ + el=document.createElement('div'); + el.classList.add('row'); + let cv=document.createElement('span'); + cv.classList.add('label'); + cv.textContent="PGN"+k; + el.appendChild(cv); + cv=document.createElement('span'); + cv.classList.add('value'); + cv.setAttribute('data-id',k); + cv.textContent=details[k]; + el.appendChild(cv); + frame.appendChild(el); + } + else{ + el.textContent=details[k]; + } + } + } window.setInterval(update,1000); window.addEventListener('load',function(){ let buttons=document.querySelectorAll('button'); @@ -79,6 +114,10 @@ let be=buttons[i]; be.onclick=window[be.id]; //assume a function with the button id } + let cd=document.getElementById("showCanDetails"); + cd.addEventListener('change',function(ev){ + showCanDetails(ev.target.checked); + }); resetForm(); }); @@ -112,6 +151,12 @@ span#connected.ok{ .buttons { padding-left: 1em; } +#canDetails{ + display:none; +} +#canDetails.visible{ + display: block; +} @@ -127,8 +172,16 @@ span#connected.ok{
- # CAN messages + # NMEA2000 messages --- +
+
+ NMEA2000 details + +
+ +
+
# TCP clients