mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-14 06:23:07 +01:00
add registerRequestHandler to the API with examples
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
#include "N2kMessages.h"
|
||||
#include "GwXdrTypeMappings.h"
|
||||
|
||||
/**
|
||||
* INVALID!!! - the next interface declaration will not work
|
||||
* as it is not in the correct header file
|
||||
@@ -144,6 +145,26 @@ String formatValue(GwApi::BoatValue *value){
|
||||
return String(buffer);
|
||||
}
|
||||
|
||||
class ExampleWebData{
|
||||
SemaphoreHandle_t lock;
|
||||
int data=0;
|
||||
public:
|
||||
ExampleWebData(){
|
||||
lock=xSemaphoreCreateMutex();
|
||||
}
|
||||
~ExampleWebData(){
|
||||
vSemaphoreDelete(lock);
|
||||
}
|
||||
void set(int v){
|
||||
GWSYNCHRONIZED(&lock);
|
||||
data=v;
|
||||
}
|
||||
int get(){
|
||||
GWSYNCHRONIZED(&lock);
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
void exampleTask(GwApi *api){
|
||||
GwLog *logger=api->getLogger();
|
||||
//get some configuration data
|
||||
@@ -172,8 +193,24 @@ void exampleTask(GwApi *api){
|
||||
LOG_DEBUG(GwLog::LOG,"exampleNotWorking update returned %d",(int)nwrs);
|
||||
String voltageTransducer=api->getConfig()->getString(GwConfigDefinitions::exTransducer);
|
||||
int voltageInstance=api->getConfig()->getInt(GwConfigDefinitions::exInstanceId);
|
||||
ExampleWebData webData;
|
||||
/**
|
||||
* an example web request handler
|
||||
* it uses a synchronized data structure as it gets called from a different thread
|
||||
* be aware that you must not block for longer times here!
|
||||
*/
|
||||
api->registerRequestHandler("data",[&webData](AsyncWebServerRequest *request){
|
||||
int data=webData.get();
|
||||
char buffer[30];
|
||||
snprintf(buffer,29,"%d",data);
|
||||
buffer[29]=0;
|
||||
request->send(200,"text/plain",buffer);
|
||||
});
|
||||
int loopcounter=0;
|
||||
while(true){
|
||||
delay(1000);
|
||||
loopcounter++;
|
||||
webData.set(loopcounter);
|
||||
/*
|
||||
* getting values from the internal data store (boatData) requires some special handling
|
||||
* our tasks runs (potentially) at some time on a different core then the main code
|
||||
|
||||
@@ -32,6 +32,26 @@ Files
|
||||
This file allows to add some config definitions that are needed for our task. For the possible options have a look at the global [config.json](../../web/config.json). Be careful not to overwrite config defitions from the global file. A good practice wood be to prefix the names of definitions with parts of the library name. Always put them in a separate category so that they do not interfere with the system ones.
|
||||
The defined config items can later be accessed in the code (see the example in [GwExampleTask.cpp](GwExampleTask.cpp)).
|
||||
|
||||
* [index.js](index.js)<br>
|
||||
You can add javascript code that will contribute to the UI of the system. The WebUI provides a small API that allows you to "hook" into some functions to include your own parts of the UI. This includes adding new tabs, modifying/replacing the data display items, modifying the status display or accessing the config items.
|
||||
For the API refer to [../../web/index.js](../../web/index.js#L2001).
|
||||
To start interacting just register for some events like api.EVENTS.init. You can check the capabilities you have defined to see if your task is active.
|
||||
By registering an own formatter [api.addUserFormatter](../../web/index.js#L2054) you can influence the way boat data items are shown.
|
||||
You can even go for an own display by registering for the event *dataItemCreated* and replace the dom element content with your own html. By additionally having added a user formatter you can now fill your own html with the current value.
|
||||
By using [api.addTabPage](../../web/index.js#L2046) you can add new tabs that you can populate with your own code. Or you can link to an external URL.<br>
|
||||
Please be aware that your js code is always combined with the code from the core into one js file.<br>
|
||||
For fast testing there is a small python script that allow you to test the UI without always flushing each change.
|
||||
Just run it with
|
||||
```
|
||||
tools/testServer.py nnn http://x.x.x.x/api
|
||||
```
|
||||
with nnn being the local port and x.x.x.x the address of a running system. Open `http://localhost:nnn` in your browser.<br>
|
||||
After a change just start the compilation and reload the page.
|
||||
|
||||
* [index.css](index.css)<br>
|
||||
You can add own css to influence the styling of the display.
|
||||
|
||||
|
||||
Interfaces
|
||||
----------
|
||||
The task init function and the task function interact with the core using an [API](../api/GwApi.h) that they get when started.
|
||||
|
||||
@@ -28,6 +28,21 @@
|
||||
//you can use the helper addEl to create elements
|
||||
let page=api.addTabPage(tabName,"Example");
|
||||
api.addEl('div','hdg',page,"this is a test tab");
|
||||
let vrow=api.addEl('div','row',page);
|
||||
api.addEl('span','label',vrow,'loops: ');
|
||||
let lcount=api.addEl('span','value',vrow,'0');
|
||||
//query the loop count
|
||||
window.setInterval(()=>{
|
||||
fetch('/api/user/exampleTask/data')
|
||||
.then((res)=>{
|
||||
if (! res.ok) throw Error("server error: "+res.status);
|
||||
return res.text();
|
||||
})
|
||||
.then((txt)=>{
|
||||
lcount.textContent=txt;
|
||||
})
|
||||
.catch((e)=>console.log("rq:",e));
|
||||
},1000);
|
||||
api.addEl('button','',page,'Info').addEventListener('click',function(ev){
|
||||
window.open(infoUrl,'info');
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user