allow to set a read only mode for config items, output compiler messages for overwritten configs, add m5 gps unit defs
This commit is contained in:
parent
9572b1e95e
commit
4fa40b98b3
|
@ -145,20 +145,33 @@ def generateCfg(inFile,outFile,addDirs=[]):
|
|||
secret="false";
|
||||
if item.get('type') == 'password':
|
||||
secret="true"
|
||||
data+=" #undef __CFGHIDDEN\n"
|
||||
data+=" #ifdef CFGHIDE_%s\n"%(name)
|
||||
data+=" #define __CFGHIDDEN true\n"
|
||||
data+=" #undef __CFGMODE\n"
|
||||
data+=" #ifdef CFGMODE_%s\n"%(name)
|
||||
data+=" #define __CFGMODE CFGMODE_%s\n"%(name)
|
||||
data+=" #else\n"
|
||||
data+=" #define __CFGHIDDEN false\n"
|
||||
data+=" #define __CFGMODE GwConfigInterface::NORMAL\n"
|
||||
data+=" #endif\n"
|
||||
data+=" #ifdef CFGDEFAULT_%s\n"%(name)
|
||||
data+=" new GwConfigInterface(%s,CFGDEFAULT_%s,%s,__CFGHIDDEN)\n"%(name,name,secret)
|
||||
data+=" #ifdef CFGDEFAULT_%s\n"%(name)
|
||||
data+=" new GwConfigInterface(%s,CFGDEFAULT_%s,%s,__CFGMODE)\n"%(name,name,secret)
|
||||
data+=" #else\n"
|
||||
data+=" new GwConfigInterface(%s,\"%s\",%s,__CFGHIDDEN)\n"%(name,item.get('default'),secret)
|
||||
data+=" new GwConfigInterface(%s,\"%s\",%s,__CFGMODE)\n"%(name,item.get('default'),secret)
|
||||
data+=" #endif\n"
|
||||
|
||||
data+='};\n'
|
||||
data+='};\n'
|
||||
data+="#ifdef CFG_MESSAGES\n"
|
||||
for item in config:
|
||||
name=item.get('name')
|
||||
if name is None:
|
||||
continue
|
||||
data+="#ifdef CFGMODE_%s\n"%(name)
|
||||
data+=" __MSG(\"CFGMODE_%s=\" __XSTR(CFGMODE_%s))\n"%(name,name)
|
||||
data+="#endif\n"
|
||||
data+="#ifdef CFGDEFAULT_%s\n"%(name)
|
||||
data+=" __MSG(\"CFGDEFAULT_%s=\" CFGDEFAULT_%s)\n"%(name,name)
|
||||
data+="#endif\n"
|
||||
data+="#endif"
|
||||
|
||||
writeFileIfChanged(outFile,data)
|
||||
|
||||
|
||||
|
@ -298,6 +311,7 @@ print("#prescript...")
|
|||
prebuild(env)
|
||||
board="PLATFORM_BOARD_%s"%env["BOARD"].replace("-","_").upper()
|
||||
print("Board=#%s#"%board)
|
||||
print("BuildFlags=%s"%(" ".join(env["BUILD_FLAGS"])))
|
||||
env.Append(
|
||||
LINKFLAGS=[ "-u", "custom_app_desc" ],
|
||||
CPPDEFINES=[(board,"1")]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#define CFG_MESSAGES
|
||||
#include "GWConfig.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <string.h>
|
||||
|
@ -159,20 +160,20 @@ void GwConfigHandler::toHex(unsigned long v, char *buffer, size_t bsize)
|
|||
buffer[2 * i] = 0;
|
||||
}
|
||||
|
||||
std::vector<String> GwConfigHandler::getHidden() const{
|
||||
std::vector<String> GwConfigHandler::getSpecial() const{
|
||||
std::vector<String> rt;
|
||||
rt.reserve(numHidden());
|
||||
rt.reserve(numSpecial());
|
||||
for (int i=0L;i<getNumConfig();i++){
|
||||
if (configs[i]->isHidden()){
|
||||
if (configs[i]->getType() != GwConfigInterface::NORMAL){
|
||||
rt.push_back(configs[i]->getName());
|
||||
};
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
int GwConfigHandler::numHidden() const{
|
||||
int GwConfigHandler::numSpecial() const{
|
||||
int rt=0;
|
||||
for (int i=0L;i<getNumConfig();i++){
|
||||
if (configs[i]->isHidden()) rt++;
|
||||
if (configs[i]->getType() != GwConfigInterface::NORMAL) rt++;
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ class GwConfigHandler: public GwConfigDefinitions{
|
|||
int getInt(const String name,int defaultv=0) const;
|
||||
GwConfigInterface * getConfigItem(const String name, bool dummy=false) const;
|
||||
bool checkPass(String hash);
|
||||
std::vector<String> getHidden() const;
|
||||
int numHidden() const;
|
||||
std::vector<String> getSpecial() const;
|
||||
int numSpecial() const;
|
||||
/**
|
||||
* change the value of a config item
|
||||
* will become a noop after stopChanges has been called
|
||||
|
|
|
@ -5,19 +5,25 @@
|
|||
|
||||
class GwConfigHandler;
|
||||
class GwConfigInterface{
|
||||
public:
|
||||
typedef enum {
|
||||
NORMAL=0,
|
||||
HIDDEN=1,
|
||||
READONLY=2
|
||||
} ConfigType;
|
||||
private:
|
||||
String name;
|
||||
const char * initialValue;
|
||||
String value;
|
||||
bool secret=false;
|
||||
bool hidden=false;
|
||||
ConfigType type=NORMAL;
|
||||
public:
|
||||
GwConfigInterface(const String &name, const char * initialValue, bool secret=false, bool hidden=false){
|
||||
GwConfigInterface(const String &name, const char * initialValue, bool secret=false,ConfigType type=NORMAL){
|
||||
this->name=name;
|
||||
this->initialValue=initialValue;
|
||||
this->value=initialValue;
|
||||
this->secret=secret;
|
||||
this->hidden=hidden;
|
||||
this->type=type;
|
||||
}
|
||||
virtual String asString() const{
|
||||
return value;
|
||||
|
@ -43,8 +49,8 @@ class GwConfigInterface{
|
|||
String getDefault() const {
|
||||
return initialValue;
|
||||
}
|
||||
bool isHidden() const {
|
||||
return hidden;
|
||||
ConfigType getType() const {
|
||||
return type;
|
||||
}
|
||||
friend class GwConfigHandler;
|
||||
};
|
||||
|
@ -67,5 +73,7 @@ class GwNmeaFilter{
|
|||
String toString();
|
||||
};
|
||||
|
||||
|
||||
#define __XSTR(x) __STR(x)
|
||||
#define __STR(x) #x
|
||||
#define __MSG(x) _Pragma (__STR(message (x)))
|
||||
#endif
|
|
@ -17,7 +17,7 @@
|
|||
#define GWSERIAL_TYPE_BI 2
|
||||
#define GWSERIAL_TYPE_RX 3
|
||||
#define GWSERIAL_TYPE_TX 4
|
||||
|
||||
#include <GwConfigItem.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include "GwUserTasks.h"
|
||||
|
||||
|
@ -148,8 +148,8 @@
|
|||
#ifdef M5_GPS_KIT
|
||||
#define GWSERIAL_RX BOARD_LEFT1
|
||||
#define GWSERIAL_TYPE GWSERIAL_TYPE_RX
|
||||
#define CFGGDEFAULT_serialBaud "9600"
|
||||
#define CFGHIDE_serialBaud
|
||||
#define CFGDEFAULT_serialBaud "9600"
|
||||
#define CFGMODE_serialBaud GwConfigInterface::READONLY
|
||||
#endif
|
||||
|
||||
//below we define the final device config based on the above
|
||||
|
@ -181,6 +181,21 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
//http://docs.m5stack.com/en/unit/gps
|
||||
#ifdef M5_GPS_UNIT
|
||||
#ifdef GWSERIAL_TYPE
|
||||
#define GWSERIAL2_RX GROOVE_PIN_2
|
||||
#define GWSERIAL2_TYPE GWSERIAL_TYPE_RX
|
||||
#define CFGDEFAULT_serialBaud "9600"
|
||||
#define CFGMODE_serialBaud GwConfigInterface::READONLY
|
||||
#else
|
||||
#define GWSERIAL_RX GROOVE_PIN_2
|
||||
#define GWSERIAL_TYPE GWSERIAL_TYPE_RX
|
||||
#define CFGDEFAULT_serial2Baud "9600"
|
||||
#define CFGMODE_serial2Baud GwConfigInterface::READONLY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//can kit for M5 Atom
|
||||
#ifdef M5_CAN_KIT
|
||||
#define ESP32_CAN_TX_PIN BOARD_LEFT1
|
||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -430,15 +430,20 @@ class CapabilitiesRequest : public GwRequestMessage{
|
|||
protected:
|
||||
virtual void processRequest(){
|
||||
int numCapabilities=userCodeHandler.getCapabilities()->size();
|
||||
int numHidden=config.numHidden();
|
||||
GwJsonDocument json(JSON_OBJECT_SIZE(numCapabilities*3+numHidden*2+8));
|
||||
int numSpecial=config.numSpecial();
|
||||
logger.logDebug(GwLog::LOG,"capabilities user=%d, config=%d",numCapabilities,numSpecial);
|
||||
GwJsonDocument json(JSON_OBJECT_SIZE(numCapabilities*3+numSpecial*2+8));
|
||||
for (auto it=userCodeHandler.getCapabilities()->begin();
|
||||
it != userCodeHandler.getCapabilities()->end();it++){
|
||||
json[it->first]=it->second;
|
||||
}
|
||||
std::vector<String> hiddenCfg=config.getHidden();
|
||||
for (auto it=hiddenCfg.begin();it != hiddenCfg.end();it++){
|
||||
json["HIDE"+*it]=true;
|
||||
std::vector<String> specialCfg=config.getSpecial();
|
||||
for (auto it=specialCfg.begin();it != specialCfg.end();it++){
|
||||
GwConfigInterface *cfg=config.getConfigItem(*it);
|
||||
if (cfg){
|
||||
logger.logDebug(GwLog::LOG,"config mode %s=%d",it->c_str(),(int)(cfg->getType()));
|
||||
json["CFGMODE"+*it]=(int)cfg->getType();
|
||||
}
|
||||
}
|
||||
json["serialmode"]=channels.getMode(SERIAL1_CHANNEL_ID);
|
||||
json["serial2mode"]=channels.getMode(SERIAL2_CHANNEL_ID);
|
||||
|
|
60
web/index.js
60
web/index.js
|
@ -231,6 +231,7 @@ function getAllConfigs(omitPass) {
|
|||
let name = v.getAttribute('name');
|
||||
if (!name) continue;
|
||||
if (name.indexOf("_") >= 0) continue;
|
||||
if (v.getAttribute('disabled')) continue;
|
||||
let def = getConfigDefition(name);
|
||||
if (def.type === 'password' && ( v.value == '' || omitPass)) {
|
||||
continue;
|
||||
|
@ -444,6 +445,7 @@ function createInput(configItem, frame,clazz) {
|
|||
let el;
|
||||
if (configItem.type === 'boolean' || configItem.type === 'list' || configItem.type == 'boatData') {
|
||||
el=addEl('select',clazz,frame);
|
||||
if (configItem.readOnly) el.setAttribute('disabled',true);
|
||||
el.setAttribute('name', configItem.name)
|
||||
let slist = [];
|
||||
if (configItem.list) {
|
||||
|
@ -476,6 +478,7 @@ function createInput(configItem, frame,clazz) {
|
|||
return createXdrInput(configItem,frame,clazz);
|
||||
}
|
||||
el = addEl('input',clazz,frame);
|
||||
if (configItem.readOnly) el.setAttribute('disabled',true);
|
||||
el.setAttribute('name', configItem.name)
|
||||
if (configItem.type === 'password') {
|
||||
el.setAttribute('type', 'password');
|
||||
|
@ -591,25 +594,29 @@ function createXdrInput(configItem,frame){
|
|||
{l:'bidir',v:1},
|
||||
{l:'to2K',v:2},
|
||||
{l:'from2K',v:3}
|
||||
]
|
||||
],
|
||||
readOnly: configItem.readOnly
|
||||
},d,'xdrdir');
|
||||
d=createXdrLine(el,'Category');
|
||||
let category=createInput({
|
||||
type: 'list',
|
||||
name: configItem.name+"_cat",
|
||||
list:getXdrCategories()
|
||||
list:getXdrCategories(),
|
||||
readOnly: configItem.readOnly
|
||||
},d,'xdrcat');
|
||||
d=createXdrLine(el,'Source');
|
||||
let selector=createInput({
|
||||
type: 'list',
|
||||
name: configItem.name+"_sel",
|
||||
list:[]
|
||||
list:[],
|
||||
readOnly: configItem.readOnly
|
||||
},d,'xdrsel');
|
||||
d=createXdrLine(el,'Field');
|
||||
let field=createInput({
|
||||
type:'list',
|
||||
name: configItem.name+'_field',
|
||||
list: []
|
||||
list: [],
|
||||
readOnly: configItem.readOnly
|
||||
},d,'xdrfield');
|
||||
d=createXdrLine(el,'Instance');
|
||||
let imode=createInput({
|
||||
|
@ -620,22 +627,26 @@ function createXdrInput(configItem,frame){
|
|||
{l:'single',v:0},
|
||||
{l:'ignore',v:1},
|
||||
{l:'auto',v:2}
|
||||
]
|
||||
],
|
||||
readOnly: configItem.readOnly
|
||||
},d,'xdrimode');
|
||||
let instance=createInput({
|
||||
type:'number',
|
||||
name: configItem.name+"_instance",
|
||||
readOnly: configItem.readOnly
|
||||
},d,'xdrinstance');
|
||||
d=createXdrLine(el,'Transducer');
|
||||
let xdrName=createInput({
|
||||
type:'text',
|
||||
name: configItem.name+"_xdr"
|
||||
name: configItem.name+"_xdr",
|
||||
readOnly: configItem.readOnly
|
||||
},d,'xdrname');
|
||||
d=createXdrLine(el,'Example');
|
||||
let example=addEl('div','xdrexample',d,'');
|
||||
let data = addEl('input','xdrvalue',el);
|
||||
data.setAttribute('type', 'hidden');
|
||||
data.setAttribute('name', configItem.name);
|
||||
if (configItem.readOnly) data.setAttribute('disabled',true);
|
||||
let changeFunction = function () {
|
||||
let parts=data.value.split(',');
|
||||
direction.value=parts[1] || 0;
|
||||
|
@ -730,16 +741,19 @@ function createFilterInput(configItem, frame) {
|
|||
let ais = createInput({
|
||||
type: 'list',
|
||||
name: configItem.name + "_ais",
|
||||
list: ['aison', 'aisoff']
|
||||
list: ['aison', 'aisoff'],
|
||||
readOnly: configItem.readOnly
|
||||
}, el);
|
||||
let mode = createInput({
|
||||
type: 'list',
|
||||
name: configItem.name + "_mode",
|
||||
list: ['whitelist', 'blacklist']
|
||||
list: ['whitelist', 'blacklist'],
|
||||
readOnly: configItem.readOnly
|
||||
}, el);
|
||||
let sentences = createInput({
|
||||
type: 'text',
|
||||
name: configItem.name + "_sentences",
|
||||
readOnly: configItem.readOnly
|
||||
}, el);
|
||||
let data = addEl('input',undefined,el);
|
||||
data.setAttribute('type', 'hidden');
|
||||
|
@ -767,6 +781,7 @@ function createFilterInput(configItem, frame) {
|
|||
changeFunction();
|
||||
});
|
||||
data.setAttribute('name', configItem.name);
|
||||
if (configItem.readOnly) data.setAttribute('disabled',true);
|
||||
return data;
|
||||
}
|
||||
let moreicons=['icon-more','icon-less'];
|
||||
|
@ -1048,8 +1063,17 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
|||
});
|
||||
if (!found) showItem=false;
|
||||
}
|
||||
|
||||
let readOnly=false;
|
||||
let mode=capabilities['CFGMODE'+item.name];
|
||||
if (mode == 1) {
|
||||
//hide
|
||||
showItem=false;
|
||||
}
|
||||
if (mode == 2){
|
||||
readOnly=true;
|
||||
}
|
||||
if (showItem) {
|
||||
item.readOnly=readOnly;
|
||||
currentCategoryPopulated=true;
|
||||
let row = addEl('div', 'row', categoryEl);
|
||||
let label = item.label || item.name;
|
||||
|
@ -1058,7 +1082,7 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
|||
let valueEl = createInput(item, valueFrame);
|
||||
if (!valueEl) return;
|
||||
valueEl.setAttribute('data-default', item.default);
|
||||
valueEl.addEventListener('change', function (ev) {
|
||||
if (! readOnly) valueEl.addEventListener('change', function (ev) {
|
||||
let el = ev.target;
|
||||
checkChange(el, row, item.name);
|
||||
})
|
||||
|
@ -1075,13 +1099,15 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
|||
}
|
||||
if (item.check) valueEl.setAttribute('data-check', item.check);
|
||||
let btContainer = addEl('div', 'buttonContainer', row);
|
||||
let bt = addEl('button', 'defaultButton', btContainer, 'X');
|
||||
bt.setAttribute('data-default', item.default);
|
||||
bt.addEventListener('click', function (ev) {
|
||||
valueEl.value = valueEl.getAttribute('data-default');
|
||||
let changeEvent = new Event('change');
|
||||
valueEl.dispatchEvent(changeEvent);
|
||||
})
|
||||
if (!readOnly) {
|
||||
let bt = addEl('button', 'defaultButton', btContainer, 'X');
|
||||
bt.setAttribute('data-default', item.default);
|
||||
bt.addEventListener('click', function (ev) {
|
||||
valueEl.value = valueEl.getAttribute('data-default');
|
||||
let changeEvent = new Event('change');
|
||||
valueEl.dispatchEvent(changeEvent);
|
||||
})
|
||||
}
|
||||
bt = addEl('button', 'infoButton', btContainer, '?');
|
||||
bt.addEventListener('click', function (ev) {
|
||||
if (item.description) {
|
||||
|
|
Loading…
Reference in New Issue