add extended nmea2k status
This commit is contained in:
parent
c24e699874
commit
63eb317816
|
@ -57,5 +57,7 @@ public:
|
||||||
virtual void loop();
|
virtual void loop();
|
||||||
virtual ~N2kDataToNMEA0183(){}
|
virtual ~N2kDataToNMEA0183(){}
|
||||||
virtual const unsigned long* handledPgns()=0;
|
virtual const unsigned long* handledPgns()=0;
|
||||||
|
virtual int numPgns()=0;
|
||||||
|
virtual void toJson(JsonDocument &json)=0;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
|
@ -90,21 +90,28 @@ private:
|
||||||
unsigned long LastPosSend;
|
unsigned long LastPosSend;
|
||||||
unsigned long NextRMCSend;
|
unsigned long NextRMCSend;
|
||||||
unsigned long lastLoopTime;
|
unsigned long lastLoopTime;
|
||||||
|
class ConverterEntry{
|
||||||
std::map<long,N2KConverter> converters;
|
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
|
* register a n2k message converter
|
||||||
* each of the converter functions must be registered in the constructor
|
* each of the converter functions must be registered in the constructor
|
||||||
**/
|
**/
|
||||||
void registerConverter(long pgn,N2KConverter converter){
|
void registerConverter(long pgn,N2KConverter converter){
|
||||||
converters[pgn]=converter;
|
ConverterEntry e(converter);
|
||||||
|
converters[pgn]=e;
|
||||||
}
|
}
|
||||||
virtual const unsigned long * handledPgns(){
|
virtual const unsigned long * handledPgns(){
|
||||||
logger->logString("CONV: # %d handled PGNS",(int)converters.size());
|
logger->logString("CONV: # %d handled PGNS",(int)converters.size());
|
||||||
unsigned long *rt=new unsigned long[converters.size()+1];
|
unsigned long *rt=new unsigned long[converters.size()+1];
|
||||||
int idx=0;
|
int idx=0;
|
||||||
for (std::map<long,N2KConverter>::iterator it=converters.begin();
|
for (ConverterMap::iterator it=converters.begin();
|
||||||
it != converters.end();it++){
|
it != converters.end();it++){
|
||||||
rt[idx]=it->first;
|
rt[idx]=it->first;
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -112,6 +119,26 @@ private:
|
||||||
rt[idx]=0;
|
rt[idx]=0;
|
||||||
return rt;
|
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; }
|
void SetNextRMCSend() { NextRMCSend = millis() + RMCPeriod; }
|
||||||
|
|
||||||
//*************** the converters ***********************
|
//*************** the converters ***********************
|
||||||
|
@ -488,7 +515,7 @@ public:
|
||||||
//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::HandleMsg);
|
registerConverter(127250UL,&N2kToNMEA0183Functions::HandleHeading);
|
||||||
registerConverter(127258UL,&N2kToNMEA0183Functions::HandleVariation);
|
registerConverter(127258UL,&N2kToNMEA0183Functions::HandleVariation);
|
||||||
registerConverter(128259UL,&N2kToNMEA0183Functions::HandleBoatSpeed);
|
registerConverter(128259UL,&N2kToNMEA0183Functions::HandleBoatSpeed);
|
||||||
registerConverter(128267UL,&N2kToNMEA0183Functions::HandleDepth);
|
registerConverter(128267UL,&N2kToNMEA0183Functions::HandleDepth);
|
||||||
|
@ -509,16 +536,5 @@ public:
|
||||||
lastLoopTime = now;
|
lastLoopTime = now;
|
||||||
SendRMC();
|
SendRMC();
|
||||||
}
|
}
|
||||||
virtual void HandleMsg(const tN2kMsg &N2kMsg)
|
|
||||||
{
|
|
||||||
std::map<long,N2KConverter>::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
|
#endif
|
|
@ -12,7 +12,7 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
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"
|
#include "GwHardware.h"
|
||||||
|
|
||||||
#define LOG_SERIAL true
|
#define LOG_SERIAL true
|
||||||
|
@ -101,12 +101,14 @@ void js_reset() // Wenn "http://<ip address>/gauge.min.js" aufgerufen wurde
|
||||||
|
|
||||||
|
|
||||||
void js_status(){
|
void js_status(){
|
||||||
StaticJsonDocument<256> status;
|
int numPgns=nmea0183Converter->numPgns();
|
||||||
|
DynamicJsonDocument status(256*numPgns*30);
|
||||||
status["numcan"]=numCan;
|
status["numcan"]=numCan;
|
||||||
status["version"]=VERSION;
|
status["version"]=VERSION;
|
||||||
status["wifiConnected"]=gwWifi.clientConnected();
|
status["wifiConnected"]=gwWifi.clientConnected();
|
||||||
status["clientIP"]=WiFi.localIP().toString();
|
status["clientIP"]=WiFi.localIP().toString();
|
||||||
status["numClients"]=socketServer.numClients();
|
status["numClients"]=socketServer.numClients();
|
||||||
|
nmea0183Converter->toJson(status);
|
||||||
String buf;
|
String buf;
|
||||||
serializeJson(status,buf);
|
serializeJson(status,buf);
|
||||||
webserver.send(200,F("application/json"),buf);
|
webserver.send(200,F("application/json"),buf);
|
||||||
|
|
|
@ -31,8 +31,13 @@
|
||||||
getJson('/api/status')
|
getJson('/api/status')
|
||||||
.then(function(jsonData){
|
.then(function(jsonData){
|
||||||
for (let k in jsonData){
|
for (let k in jsonData){
|
||||||
let el=document.getElementById(k);
|
if (k == 'cnv'){
|
||||||
if (el) el.textContent=jsonData[k];
|
updateCanDetails(jsonData[k]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
let el=document.getElementById(k);
|
||||||
|
if (el) el.textContent=jsonData[k];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lastUpdate=(new Date()).getTime();
|
lastUpdate=(new Date()).getTime();
|
||||||
})
|
})
|
||||||
|
@ -72,6 +77,36 @@
|
||||||
alertRestart();
|
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.setInterval(update,1000);
|
||||||
window.addEventListener('load',function(){
|
window.addEventListener('load',function(){
|
||||||
let buttons=document.querySelectorAll('button');
|
let buttons=document.querySelectorAll('button');
|
||||||
|
@ -79,6 +114,10 @@
|
||||||
let be=buttons[i];
|
let be=buttons[i];
|
||||||
be.onclick=window[be.id]; //assume a function with the button id
|
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();
|
resetForm();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -112,6 +151,12 @@ span#connected.ok{
|
||||||
.buttons {
|
.buttons {
|
||||||
padding-left: 1em;
|
padding-left: 1em;
|
||||||
}
|
}
|
||||||
|
#canDetails{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
#canDetails.visible{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
@ -127,8 +172,16 @@ span#connected.ok{
|
||||||
<span class="value" id="connected"></span>
|
<span class="value" id="connected"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="label"># CAN messages</span>
|
<span class="label"># NMEA2000 messages</span>
|
||||||
<span class="value" id="numcan">---</span>
|
<span class="value" id="numcan">---</span>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span class="label">NMEA2000 details</span>
|
||||||
|
<input type="checkbox" id="showCanDetails"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" id="canDetails">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="label"># TCP clients</span>
|
<span class="label"># TCP clients</span>
|
||||||
|
|
Loading…
Reference in New Issue