add info about conversions to UI, tweak layout

This commit is contained in:
andreas 2021-11-05 19:19:43 +01:00
parent 4572cafa23
commit fc57d73054
7 changed files with 99 additions and 9 deletions

View File

@ -13,7 +13,8 @@ public:
typedef void (*LConverter)(const Msg &msg, T *); typedef void (*LConverter)(const Msg &msg, T *);
private: private:
double dummy; String keyList;
bool keyListFilled=false;
class ConverterEntry class ConverterEntry
{ {
public: public:
@ -44,7 +45,7 @@ private:
typedef std::map<String, ConverterEntry> ConverterMap; typedef std::map<String, ConverterEntry> ConverterMap;
ConverterMap converters; ConverterMap converters;
public: public:
/** /**
* register a converter * register a converter
* each of the converter functions must be registered in the constructor * each of the converter functions must be registered in the constructor
@ -54,70 +55,82 @@ public:
unsigned long *lpgn=new unsigned long[1]{pgn}; unsigned long *lpgn=new unsigned long[1]{pgn};
ConverterEntry e(1,lpgn, converter); ConverterEntry e(1,lpgn, converter);
converters[String(pgn)] = e; converters[String(pgn)] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, LConverter converter) void registerConverter(unsigned long pgn, LConverter converter)
{ {
unsigned long *lpgn=new unsigned long[1]{pgn}; unsigned long *lpgn=new unsigned long[1]{pgn};
ConverterEntry e(1,lpgn, converter); ConverterEntry e(1,lpgn, converter);
converters[String(pgn)] = e; converters[String(pgn)] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, String sentence, Converter converter) void registerConverter(unsigned long pgn, String sentence, Converter converter)
{ {
unsigned long *lpgn=new unsigned long[1]{pgn}; unsigned long *lpgn=new unsigned long[1]{pgn};
ConverterEntry e(1,lpgn, converter); ConverterEntry e(1,lpgn, converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, String sentence, LConverter converter) void registerConverter(unsigned long pgn, String sentence, LConverter converter)
{ {
unsigned long *lpgn=new unsigned long[1]{pgn}; unsigned long *lpgn=new unsigned long[1]{pgn};
ConverterEntry e(1,lpgn, converter); ConverterEntry e(1,lpgn, converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(int num,unsigned long *lpgn, String sentence, Converter converter) void registerConverter(int num,unsigned long *lpgn, String sentence, Converter converter)
{ {
ConverterEntry e(num,lpgn, converter); ConverterEntry e(num,lpgn, converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(int num,unsigned long *lpgn, String sentence, LConverter converter) void registerConverter(int num,unsigned long *lpgn, String sentence, LConverter converter)
{ {
ConverterEntry e(num,lpgn, converter); ConverterEntry e(num,lpgn, converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, unsigned long pgn2, String sentence, Converter converter) void registerConverter(unsigned long pgn, unsigned long pgn2, String sentence, Converter converter)
{ {
unsigned long *lpgn=new unsigned long[2]{pgn,pgn2}; unsigned long *lpgn=new unsigned long[2]{pgn,pgn2};
ConverterEntry e(2, lpgn, converter); ConverterEntry e(2, lpgn, converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, unsigned long pgn2, String sentence, LConverter converter) void registerConverter(unsigned long pgn, unsigned long pgn2, String sentence, LConverter converter)
{ {
unsigned long *lpgn=new unsigned long[2]{pgn,pgn2}; unsigned long *lpgn=new unsigned long[2]{pgn,pgn2};
ConverterEntry e(2, lpgn, converter); ConverterEntry e(2, lpgn, converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,String sentence, Converter converter) void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,String sentence, Converter converter)
{ {
unsigned long *lpgn=new unsigned long[3]{pgn,pgn2,pgn3}; unsigned long *lpgn=new unsigned long[3]{pgn,pgn2,pgn3};
ConverterEntry e(3, lpgn,converter); ConverterEntry e(3, lpgn,converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,String sentence, LConverter converter) void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,String sentence, LConverter converter)
{ {
unsigned long *lpgn=new unsigned long[3]{pgn,pgn2,pgn3}; unsigned long *lpgn=new unsigned long[3]{pgn,pgn2,pgn3};
ConverterEntry e(3, lpgn,converter); ConverterEntry e(3, lpgn,converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,unsigned long pgn4,String sentence, Converter converter) void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,unsigned long pgn4,String sentence, Converter converter)
{ {
unsigned long *lpgn=new unsigned long[4]{pgn,pgn2,pgn3,pgn4}; unsigned long *lpgn=new unsigned long[4]{pgn,pgn2,pgn3,pgn4};
ConverterEntry e(4, lpgn,converter); ConverterEntry e(4, lpgn,converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,unsigned long pgn4,String sentence, LConverter converter) void registerConverter(unsigned long pgn, unsigned long pgn2, unsigned long pgn3,unsigned long pgn4,String sentence, LConverter converter)
{ {
unsigned long *lpgn=new unsigned long[4]{pgn,pgn2,pgn3,pgn4}; unsigned long *lpgn=new unsigned long[4]{pgn,pgn2,pgn3,pgn4};
ConverterEntry e(4, lpgn,converter); ConverterEntry e(4, lpgn,converter);
converters[sentence] = e; converters[sentence] = e;
keyListFilled=false;
} }
bool handleMessage(String code, const Msg &msg, T *base) bool handleMessage(String code, const Msg &msg, T *base)
@ -182,5 +195,18 @@ public:
json[prefix][String(it->first)] = it->second.count; json[prefix][String(it->first)] = it->second.count;
} }
} }
String handledKeys(){
if (! keyListFilled){
keyList=String();
bool first=true;
for (auto it=converters.begin();it != converters.end();it++){
if (! first) keyList.concat(',');
first=false;
keyList.concat(it->first);
}
keyListFilled=true;
}
return keyList;
}
}; };
#endif #endif

View File

@ -402,6 +402,9 @@ public:
virtual int numConverters(){ virtual int numConverters(){
return converters.numConverters(); return converters.numConverters();
} }
virtual String handledKeys(){
return converters.handledKeys();
}
NMEA0183DataToN2KFunctions(GwLog *logger, GwBoatData *boatData, N2kSender callback) NMEA0183DataToN2KFunctions(GwLog *logger, GwBoatData *boatData, N2kSender callback)
: NMEA0183DataToN2K(logger, boatData, callback) : NMEA0183DataToN2K(logger, boatData, callback)

View File

@ -16,6 +16,7 @@ class NMEA0183DataToN2K{
virtual bool parseAndSend(const char *buffer, int sourceId); virtual bool parseAndSend(const char *buffer, int sourceId);
virtual unsigned long *handledPgns()=0; virtual unsigned long *handledPgns()=0;
virtual int numConverters()=0; virtual int numConverters()=0;
virtual String handledKeys()=0;
static NMEA0183DataToN2K* create(GwLog *logger,GwBoatData *boatData,N2kSender callback); static NMEA0183DataToN2K* create(GwLog *logger,GwBoatData *boatData,N2kSender callback);
}; };
#endif #endif

View File

@ -92,6 +92,9 @@ private:
logger->logString("CONV: # %d handled PGNS", converters.numConverters()); logger->logString("CONV: # %d handled PGNS", converters.numConverters());
return converters.handledPgns(); return converters.handledPgns();
} }
virtual String handledKeys(){
return converters.handledKeys();
}
virtual void HandleMsg(const tN2kMsg &N2kMsg) virtual void HandleMsg(const tN2kMsg &N2kMsg)
{ {
String key=String(N2kMsg.PGN); String key=String(N2kMsg.PGN);

View File

@ -51,5 +51,6 @@ public:
virtual unsigned long* handledPgns()=0; virtual unsigned long* handledPgns()=0;
virtual int numPgns()=0; virtual int numPgns()=0;
virtual void toJson(JsonDocument &json)=0; virtual void toJson(JsonDocument &json)=0;
virtual String handledKeys()=0;
}; };
#endif #endif

View File

@ -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.5.1" #define VERSION "0.5.2"
// #define GW_MESSAGE_DEBUG_ENABLED // #define GW_MESSAGE_DEBUG_ENABLED
// #define FALLBACK_SERIAL // #define FALLBACK_SERIAL
@ -189,6 +189,21 @@ class CapabilitiesRequest : public GwRequestMessage{
serializeJson(json,result); serializeJson(json,result);
} }
}; };
class ConverterInfoRequest : public GwRequestMessage{
public:
ConverterInfoRequest() : GwRequestMessage(F("application/json"),F("converterInfo")){};
protected:
virtual void processRequest(){
DynamicJsonDocument json(512);
String keys=toN2KConverter->handledKeys();
logger.logDebug(GwLog::DEBUG,"handled nmea0183: %s",keys.c_str());
json["nmea0183"]=keys;
keys=nmea0183Converter->handledKeys();
logger.logDebug(GwLog::DEBUG,"handled nmea2000: %s",keys.c_str());
json["nmea2000"]=keys;
serializeJson(json,result);
}
};
class ConfigRequest : public GwRequestMessage class ConfigRequest : public GwRequestMessage
{ {
public: public:
@ -346,6 +361,9 @@ void setup() {
webserver.registerMainHandler("/api/capabilities", [](AsyncWebServerRequest *request)->GwRequestMessage *{ webserver.registerMainHandler("/api/capabilities", [](AsyncWebServerRequest *request)->GwRequestMessage *{
return new CapabilitiesRequest(); return new CapabilitiesRequest();
}); });
webserver.registerMainHandler("/api/converterInfo", [](AsyncWebServerRequest *request)->GwRequestMessage *{
return new ConverterInfoRequest();
});
webserver.registerMainHandler("/api/status", [](AsyncWebServerRequest *request)->GwRequestMessage * webserver.registerMainHandler("/api/status", [](AsyncWebServerRequest *request)->GwRequestMessage *
{ return new StatusRequest(); }); { return new StatusRequest(); });
webserver.registerMainHandler("/api/config", [](AsyncWebServerRequest *request)->GwRequestMessage * webserver.registerMainHandler("/api/config", [](AsyncWebServerRequest *request)->GwRequestMessage *

View File

@ -146,9 +146,16 @@
} }
} }
} }
function showOverlay(text){ function showOverlay(text,isHtml){
let el=document.getElementById('overlayContent'); let el=document.getElementById('overlayContent');
el.textContent=text; if (isHtml){
el.innerHTML=text;
el.classList.remove("text");
}
else{
el.textContent=text;
el.classList.add("text");
}
let container=document.getElementById('overlayContainer'); let container=document.getElementById('overlayContainer');
container.classList.remove('hidden'); container.classList.remove('hidden');
} }
@ -282,7 +289,10 @@
labelEl.classList.add('label'); labelEl.classList.add('label');
labelEl.textContent = label; labelEl.textContent = label;
row.appendChild(labelEl); row.appendChild(labelEl);
let valueEl = createInput(item,row); let valueFrame=document.createElement("div");
valueFrame.classList.add("value");
row.appendChild(valueFrame);
let valueEl = createInput(item,valueFrame);
if (!valueEl) return; if (!valueEl) return;
valueEl.setAttribute('data-default', item.default); valueEl.setAttribute('data-default', item.default);
valueEl.addEventListener('change', function (ev) { valueEl.addEventListener('change', function (ev) {
@ -290,6 +300,9 @@
checkChange(el,row); checkChange(el,row);
}) })
if (item.check) valueEl.setAttribute('data-check', item.check); if (item.check) valueEl.setAttribute('data-check', item.check);
let btContainer=document.createElement("div");
btContainer.classList.add("buttonContainer");
row.appendChild(btContainer);
let bt = document.createElement('button'); let bt = document.createElement('button');
bt.classList.add('defaultButton'); bt.classList.add('defaultButton');
bt.setAttribute('data-default', item.default); bt.setAttribute('data-default', item.default);
@ -299,14 +312,14 @@
valueEl.dispatchEvent(changeEvent); valueEl.dispatchEvent(changeEvent);
}) })
bt.textContent = "X"; bt.textContent = "X";
row.appendChild(bt); btContainer.appendChild(bt);
bt = document.createElement('button'); bt = document.createElement('button');
bt.classList.add('infoButton'); bt.classList.add('infoButton');
bt.addEventListener('click', function (ev) { bt.addEventListener('click', function (ev) {
showOverlay(item.description); showOverlay(item.description);
}); });
bt.textContent = "?"; bt.textContent = "?";
row.appendChild(bt); btContainer.appendChild(bt);
frame.appendChild(row); frame.appendChild(row);
}) })
resetForm(); resetForm();
@ -314,6 +327,18 @@
}) })
.catch(function (err) { alert("unable to load config: " + err) }) .catch(function (err) { alert("unable to load config: " + err) })
} }
function converterInfo(){
getJson("api/converterInfo").then(function(json){
let text="<h3>Converted entities</h3>";
text+="<p><b>NMEA0183 to NMEA2000:</b><br/>";
text+=" "+(json.nmea0183||"").replace(/,/g,", ");
text+="</p>";
text+="<p><b>NMEA2000 to NMEA0183:</b><br/>";
text+=" "+(json.nmea2000||"").replace(/,/g,", ");
text+="</p>";
showOverlay(text,true);
});
}
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');
@ -348,6 +373,11 @@ span.label {
display: inline-block; display: inline-block;
opacity: 0.6; opacity: 0.6;
} }
.value {
width: 19em;
display: flex;
flex-direction: row;
}
span#connected { span#connected {
display: inline-block; display: inline-block;
background-color: red; background-color: red;
@ -360,6 +390,9 @@ span#connected.ok{
} }
.row { .row {
margin: 0.5em; margin: 0.5em;
display: flex;
flex-direction: row;
flex-wrap: wrap;
} }
.filter { .filter {
display: inline-block; display: inline-block;
@ -394,10 +427,14 @@ div#overlay {
margin: auto; margin: auto;
background-color: white; background-color: white;
padding: 0.5em; padding: 0.5em;
max-width: 100%;
box-sizing: border-box;
} }
div#overlayContent { div#overlayContent {
padding: 0.5em; padding: 0.5em;
white-space: pre; }
div#overlayContent.text{
white-space: pre;
} }
.overlayButtons { .overlayButtons {
border-top: 1px solid grey; border-top: 1px solid grey;
@ -414,6 +451,7 @@ div#overlayContent {
<div class="row"> <div class="row">
<span class="label">VERSION</span> <span class="label">VERSION</span>
<span class="value" id="version">---</span> <span class="value" id="version">---</span>
<button class="infoButton" id="converterInfo">?</button>
</div> </div>
<div class="row"> <div class="row">
<span class="label">connected</span> <span class="label">connected</span>