mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-13 05:53:06 +01:00
allow usercode to define config and set capabilities
This commit is contained in:
@@ -19,4 +19,7 @@ class GwApi{
|
||||
#ifndef DECLARE_USERTASK
|
||||
#define DECLARE_USERTASK(task)
|
||||
#endif
|
||||
#ifndef DECLARE_CAPABILITY
|
||||
#define DECLARE_CAPABILITY(name,value)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -35,10 +35,15 @@ class GetBoatDataRequest: public GwMessage{
|
||||
void exampleTask(void *param){
|
||||
GwApi *api=(GwApi*)param;
|
||||
GwLog *logger=api->getLogger();
|
||||
//get some configuration data
|
||||
bool exampleSwitch=api->getConfig()->getConfigItem(
|
||||
api->getConfig()->exampleConfig,
|
||||
true)->asBoolean();
|
||||
//------
|
||||
//initialization goes here
|
||||
//------
|
||||
bool hasPosition=false;
|
||||
LOG_DEBUG(GwLog::DEBUG,"example switch ist %s",exampleSwitch?"true":"false");
|
||||
while(true){
|
||||
delay(1000);
|
||||
/*
|
||||
@@ -65,14 +70,14 @@ void exampleTask(void *param){
|
||||
}
|
||||
if (r->latitude == INVALID_COORD || r->longitude == INVALID_COORD){
|
||||
if (hasPosition){
|
||||
logger->logDebug(GwLog::ERROR,"position lost...");
|
||||
if (exampleSwitch) logger->logDebug(GwLog::ERROR,"position lost...");
|
||||
hasPosition=false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
//do something with the data we have from boatData
|
||||
if (! hasPosition){
|
||||
logger->logDebug(GwLog::LOG,"postion now available lat=%f, lon=%f",
|
||||
if (exampleSwitch) logger->logDebug(GwLog::LOG,"postion now available lat=%f, lon=%f",
|
||||
r->latitude,r->longitude);
|
||||
hasPosition=true;
|
||||
}
|
||||
|
||||
@@ -7,5 +7,9 @@
|
||||
void exampleTask(void *param);
|
||||
//make the task known to the core
|
||||
DECLARE_USERTASK(exampleTask);
|
||||
//we declare a capability that we can
|
||||
//use in config.json to only show some
|
||||
//elements when this capability is set correctly
|
||||
DECLARE_CAPABILITY(testboard,true);
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
Extending the Core
|
||||
==================
|
||||
This directory contains an example on how you can extend the base functionality of the gateway.
|
||||
Basically you can define own boards here and can add one or more tasks that will be started by the core.
|
||||
You can also add additional libraries that will be used for your task.
|
||||
Maybe you have another interesting hardware or need some additional functions but would like to use the base functionality of the gateway.
|
||||
You can define own hardware configurations (environments) here and can add one or more tasks that will be started by the core.
|
||||
You can also add additional libraries that will be used to build your task.
|
||||
In this example we define an addtional board (environment) with the name "testboard".
|
||||
When building for this board we add the -DTEST_BOARD to the compilation - see [platformio.ini](platformio.ini).
|
||||
The additional task that we defined will only be compiled and started for this environment (see the #ifdef TEST_BOARD in the code).
|
||||
@@ -10,22 +11,41 @@ You can add your own directory below "lib". The name of the directory must conta
|
||||
|
||||
Files
|
||||
-----
|
||||
* [platformio.ini](platformio.ini)
|
||||
extend the base configuration - we add a dummy library here and define our buil environment (board)
|
||||
* [GwExampleTask.h](GwExampleTask.h) the name of this include must match the name of the directory (ignoring case) with a "gw" in front. This file includes our special hardware definitions and registers our task at the core (DECLARE_USERTASK in the code).
|
||||
* [platformio.ini](platformio.ini)<br>
|
||||
This file is completely optional.
|
||||
You only need this if you want to
|
||||
extend the base configuration - we add a dummy library here and define one additional build environment (board)
|
||||
* [GwExampleTask.h](GwExampleTask.h) the name of this include must match the name of the directory (ignoring case) with a "gw" in front. This file includes our special hardware definitions and registers our task at the core (DECLARE_USERTASK in the code). Optionally it can define some capabilities (using DECLARE_CAPABILITY) that can be used in the config UI (see below).
|
||||
Avoid including headers from other libraries in this file as this could interfere with the main code. Just only include them in your .cpp files (or in other headers).
|
||||
* [GwExampleTaks.cpp](GwExampleTask.cpp) includes the implementation of our task. This tasks runs in an own thread - see the comments in the code.
|
||||
We can have as many cpp (and header files) as we need to structure our code.
|
||||
* [GwExampleHardware.h](GwExampleHardware.h) includes our pin definitions for the board.
|
||||
* [config.json](config.json)<br>
|
||||
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)).
|
||||
|
||||
Hints
|
||||
-----
|
||||
Just be careful not to interfere with names from the core - so it is a good practice to prefix your files and class like in the example.
|
||||
Just be careful not to interfere with C symbols from the core - so it is a good practice to prefix your files and class like in the example.
|
||||
|
||||
Developing
|
||||
----------
|
||||
To develop I recommend forking the gateway repository and adding your own directory below lib (with the string task in it's name).
|
||||
As your code goes into a separate directory it should be very easy to fetch upstream changes without the need to adapt your code.
|
||||
Typically after forking the repo on github (https://github.com/wellenvogel/esp32-nmea2000) and initially cloning it you will add my repository as an "upstream repo":
|
||||
```
|
||||
git remote add upstream https://github.com/wellenvogel/esp32-nmea2000.git
|
||||
```
|
||||
To merge in a new version use:
|
||||
```
|
||||
git fetch upstream
|
||||
git merge upstream/master
|
||||
```
|
||||
Refer to https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork
|
||||
|
||||
By following the hints in this doc the merge should always succeed without conflicts.
|
||||
|
||||
Future Plans
|
||||
------------
|
||||
If there will be a need we can extend this extension API by means of adding config items and specific java script code and css for the UI.
|
||||
If there will be a need we can extend this extension API by means of adding specific java script code and css for the UI.
|
||||
|
||||
|
||||
13
lib/exampletask/config.json
Normal file
13
lib/exampletask/config.json
Normal file
@@ -0,0 +1,13 @@
|
||||
[
|
||||
{
|
||||
"name": "exampleConfig",
|
||||
"label": "logging on",
|
||||
"type": "boolean",
|
||||
"default": "false",
|
||||
"description": "switch on logging of position acquired/failed",
|
||||
"category": "example",
|
||||
"capabilities": {
|
||||
"testboard":"true"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "GwUserCode.h"
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
//user task handling
|
||||
class UserTask{
|
||||
public:
|
||||
@@ -11,7 +12,9 @@ class UserTask{
|
||||
this->task=task;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<UserTask> userTasks;
|
||||
GwUserCode::Capabilities userCapabilities;
|
||||
|
||||
void registerUserTask(TaskFunction_t task,String name){
|
||||
userTasks.push_back(UserTask(name,task));
|
||||
@@ -23,7 +26,14 @@ class GwUserTask{
|
||||
registerUserTask(task,name);
|
||||
}
|
||||
};
|
||||
class GwUserCapability{
|
||||
public:
|
||||
GwUserCapability(String name,String value){
|
||||
userCapabilities[name]=value;
|
||||
}
|
||||
};
|
||||
#define DECLARE_USERTASK(task) GwUserTask __##task##__(task,#task);
|
||||
#define DECLARE_CAPABILITY(name,value) GwUserCapability __CAP##name__(#name,#value);
|
||||
#include "GwUserTasks.h"
|
||||
#include "GwApi.h"
|
||||
class TaskApi : public GwApi
|
||||
@@ -86,4 +96,8 @@ void GwUserCode::startUserTasks(int baseId){
|
||||
void GwUserCode::startAddonTask(String name, TaskFunction_t task, int id){
|
||||
LOG_DEBUG(GwLog::LOG,"starting addon task %s with id %d",name.c_str(),id);
|
||||
startAddOnTask(api,task,id);
|
||||
}
|
||||
|
||||
GwUserCode::Capabilities * GwUserCode::getCapabilities(){
|
||||
return &userCapabilities;
|
||||
}
|
||||
@@ -1,14 +1,17 @@
|
||||
#ifndef _GWUSERCODE_H
|
||||
#define _GWUSERCODE_H
|
||||
#include <Arduino.h>
|
||||
#include <map>
|
||||
class GwLog;
|
||||
class GwApi;
|
||||
class GwUserCode{
|
||||
GwLog *logger;
|
||||
GwApi *api;
|
||||
public:
|
||||
typedef std::map<String,String> Capabilities;
|
||||
GwUserCode(GwApi *api);
|
||||
void startUserTasks(int baseId);
|
||||
void startAddonTask(String name,TaskFunction_t task, int id);
|
||||
Capabilities *getCapabilities();
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user