Merge branch 'master' of https://github.com/wellenvogel/esp32-nmea2000 into feature/env2
This commit is contained in:
commit
eb7239f27e
149
extra_script.py
149
extra_script.py
|
@ -10,10 +10,18 @@ Import("env")
|
||||||
GEN_DIR='generated'
|
GEN_DIR='generated'
|
||||||
CFG_FILE='web/config.json'
|
CFG_FILE='web/config.json'
|
||||||
XDR_FILE='web/xdrconfig.json'
|
XDR_FILE='web/xdrconfig.json'
|
||||||
FILES=['web/index.html',CFG_FILE,XDR_FILE,'web/index.js','web/index.css']
|
|
||||||
CFG_INCLUDE='GwConfigDefinitions.h'
|
CFG_INCLUDE='GwConfigDefinitions.h'
|
||||||
XDR_INCLUDE='GwXdrTypeMappings.h'
|
XDR_INCLUDE='GwXdrTypeMappings.h'
|
||||||
|
EMBEDDED_INCLUDE="GwEmbeddedFiles.h"
|
||||||
|
|
||||||
|
def getEmbeddedFiles(env):
|
||||||
|
rt=[]
|
||||||
|
efiles=env.GetProjectOption("board_build.embed_files")
|
||||||
|
for f in efiles.split("\n"):
|
||||||
|
if f == '':
|
||||||
|
continue
|
||||||
|
rt.append(f)
|
||||||
|
return rt
|
||||||
|
|
||||||
def basePath():
|
def basePath():
|
||||||
#see: https://stackoverflow.com/questions/16771894/python-nameerror-global-name-file-is-not-defined
|
#see: https://stackoverflow.com/questions/16771894/python-nameerror-global-name-file-is-not-defined
|
||||||
|
@ -38,29 +46,45 @@ def isCurrent(infile,outfile):
|
||||||
print("%s is newer then %s, no need to recreate"%(outfile,infile))
|
print("%s is newer then %s, no need to recreate"%(outfile,infile))
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
def compressFile(inFile):
|
def compressFile(inFile,outfile):
|
||||||
outfile=os.path.basename(inFile)+".gz"
|
|
||||||
inFile=os.path.join(basePath(),inFile)
|
|
||||||
outfile=os.path.join(outPath(),outfile)
|
|
||||||
if isCurrent(inFile,outfile):
|
if isCurrent(inFile,outfile):
|
||||||
return
|
return
|
||||||
with open(inFile, 'rb') as f_in:
|
with open(inFile, 'rb') as f_in:
|
||||||
with gzip.open(outfile, 'wb') as f_out:
|
with gzip.open(outfile, 'wb') as f_out:
|
||||||
shutil.copyfileobj(f_in, f_out)
|
shutil.copyfileobj(f_in, f_out)
|
||||||
|
|
||||||
|
def generateFile(infile,outfile,callback,inMode='rb',outMode='w'):
|
||||||
def generateCfg():
|
|
||||||
outfile=os.path.join(outPath(),CFG_INCLUDE)
|
|
||||||
infile=os.path.join(basePath(),CFG_FILE)
|
|
||||||
if isCurrent(infile,outfile):
|
if isCurrent(infile,outfile):
|
||||||
return
|
return
|
||||||
print("creating %s"%CFG_INCLUDE)
|
print("creating %s"%outfile)
|
||||||
oh=None
|
oh=None
|
||||||
with open(CFG_FILE,'rb') as ch:
|
with open(infile,inMode) as ch:
|
||||||
config=json.load(ch)
|
|
||||||
try:
|
|
||||||
with open(outfile,'w') as oh:
|
with open(outfile,'w') as oh:
|
||||||
oh.write("//generated from %s\n"%CFG_FILE)
|
try:
|
||||||
|
callback(ch,oh,inFile=infile)
|
||||||
|
oh.close()
|
||||||
|
except Exception as e:
|
||||||
|
try:
|
||||||
|
oh.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
os.unlink(outfile)
|
||||||
|
raise
|
||||||
|
|
||||||
|
def writeFileIfChanged(fileName,data):
|
||||||
|
if os.path.exists(fileName):
|
||||||
|
with open(fileName,"r") as ih:
|
||||||
|
old=ih.read()
|
||||||
|
ih.close()
|
||||||
|
if old == data:
|
||||||
|
return
|
||||||
|
print("#generating %s"%fileName)
|
||||||
|
with open(fileName,"w") as oh:
|
||||||
|
oh.write(data)
|
||||||
|
|
||||||
|
def generateCfg(ch,oh,inFile=''):
|
||||||
|
config=json.load(ch)
|
||||||
|
oh.write("//generated from %s\n"%inFile)
|
||||||
oh.write('#include "GwConfigItem.h"\n')
|
oh.write('#include "GwConfigItem.h"\n')
|
||||||
l=len(config)
|
l=len(config)
|
||||||
oh.write('class GwConfigDefinitions{\n')
|
oh.write('class GwConfigDefinitions{\n')
|
||||||
|
@ -83,28 +107,10 @@ def generateCfg():
|
||||||
oh.write(" new GwConfigItem(%s,\"%s\")"%(item.get('name'),item.get('default')))
|
oh.write(" new GwConfigItem(%s,\"%s\")"%(item.get('name'),item.get('default')))
|
||||||
oh.write('};\n')
|
oh.write('};\n')
|
||||||
oh.write('};\n')
|
oh.write('};\n')
|
||||||
oh.close()
|
|
||||||
except Exception as e:
|
|
||||||
if oh is not None:
|
|
||||||
try:
|
|
||||||
oh.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
os.unlink(outfile)
|
|
||||||
raise
|
|
||||||
|
|
||||||
def generateXdrMappings():
|
|
||||||
outfile=os.path.join(outPath(),XDR_INCLUDE)
|
|
||||||
infile=os.path.join(basePath(),XDR_FILE)
|
|
||||||
if isCurrent(infile,outfile):
|
|
||||||
return
|
|
||||||
print("creating %s"%XDR_INCLUDE)
|
|
||||||
oh=None
|
|
||||||
|
|
||||||
with open(infile,"rb") as fp:
|
def generateXdrMappings(fp,oh,inFile=''):
|
||||||
jdoc=json.load(fp)
|
jdoc=json.load(fp)
|
||||||
try:
|
|
||||||
with open(outfile,"w") as oh:
|
|
||||||
oh.write("static GwXDRTypeMapping* typeMappings[]={\n")
|
oh.write("static GwXDRTypeMapping* typeMappings[]={\n")
|
||||||
first=True
|
first=True
|
||||||
for cat in jdoc:
|
for cat in jdoc:
|
||||||
|
@ -118,7 +124,7 @@ def generateXdrMappings():
|
||||||
first=False
|
first=False
|
||||||
else:
|
else:
|
||||||
oh.write(",\n")
|
oh.write(",\n")
|
||||||
oh.write(" new GwXDRTypeMapping(%d,%d,0) /*%s*/"%(cid,tc,cat))
|
oh.write(" new GwXDRTypeMapping(%d,0,%d) /*%s*/"%(cid,tc,cat))
|
||||||
fields=item.get('fields')
|
fields=item.get('fields')
|
||||||
if fields is None:
|
if fields is None:
|
||||||
continue
|
continue
|
||||||
|
@ -138,26 +144,67 @@ def generateXdrMappings():
|
||||||
first=False
|
first=False
|
||||||
else:
|
else:
|
||||||
oh.write(",\n")
|
oh.write(",\n")
|
||||||
oh.write(" new GwXDRTypeMapping(%d,%d,%d) /*%s:%s*/"%(cid,tc,id,cat,l))
|
oh.write(" new GwXDRTypeMapping(%d,%d,%d) /*%s:%s*/"%(cid,id,tc,cat,l))
|
||||||
oh.write("\n")
|
oh.write("\n")
|
||||||
oh.write("};\n")
|
oh.write("};\n")
|
||||||
except Exception as e:
|
|
||||||
if oh:
|
|
||||||
try:
|
|
||||||
oh.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
os.unlink(outfile)
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
def generateEmbedded(elist,outFile):
|
||||||
|
content=""
|
||||||
|
for entry in elist:
|
||||||
|
content+="EMBED_GZ_FILE(\"%s\",%s,\"%s\");\n"%entry
|
||||||
|
writeFileIfChanged(outFile,content)
|
||||||
|
|
||||||
|
def getContentType(fn):
|
||||||
|
if (fn.endswith('.gz')):
|
||||||
|
fn=fn[0:-3]
|
||||||
|
if (fn.endswith('html')):
|
||||||
|
return "text/html"
|
||||||
|
if (fn.endswith('json')):
|
||||||
|
return "application/json"
|
||||||
|
if (fn.endswith('js')):
|
||||||
|
return "text/javascript"
|
||||||
|
if (fn.endswith('css')):
|
||||||
|
return "text/css"
|
||||||
|
return "application/octet-stream"
|
||||||
|
|
||||||
if not checkDir():
|
def prebuild(env):
|
||||||
|
print("#prebuild running")
|
||||||
|
if not checkDir():
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
for f in FILES:
|
embedded=getEmbeddedFiles(env)
|
||||||
print("compressing %s"%f)
|
filedefs=[]
|
||||||
compressFile(f)
|
for ef in embedded:
|
||||||
generateCfg()
|
print("#checking embedded file %s"%ef)
|
||||||
generateXdrMappings()
|
(dn,fn)=os.path.split(ef)
|
||||||
version="dev"+datetime.now().strftime("%Y%m%d")
|
pureName=fn
|
||||||
env.Append(CPPDEFINES=[('GWDEVVERSION',version)])
|
if pureName.endswith('.gz'):
|
||||||
|
pureName=pureName[0:-3]
|
||||||
|
ct=getContentType(pureName)
|
||||||
|
usname=ef.replace('/','_').replace('.','_')
|
||||||
|
filedefs.append((pureName,usname,ct))
|
||||||
|
inFile=os.path.join(basePath(),"web",pureName)
|
||||||
|
if os.path.exists(inFile):
|
||||||
|
print("compressing %s"%inFile)
|
||||||
|
compressFile(inFile,ef)
|
||||||
|
else:
|
||||||
|
print("#WARNING: infile %s for %s not found"%(inFile,ef))
|
||||||
|
generateEmbedded(filedefs,os.path.join(outPath(),EMBEDDED_INCLUDE))
|
||||||
|
generateFile(os.path.join(basePath(),CFG_FILE),os.path.join(outPath(),CFG_INCLUDE),generateCfg)
|
||||||
|
generateFile(os.path.join(basePath(),XDR_FILE),os.path.join(outPath(),XDR_INCLUDE),generateXdrMappings)
|
||||||
|
version="dev"+datetime.now().strftime("%Y%m%d")
|
||||||
|
env.Append(CPPDEFINES=[('GWDEVVERSION',version)])
|
||||||
|
|
||||||
|
def cleangenerated(source, target, env):
|
||||||
|
od=outPath()
|
||||||
|
if os.path.isdir(od):
|
||||||
|
print("#cleaning up %s"%od)
|
||||||
|
for f in os.listdir(od):
|
||||||
|
if f == "." or f == "..":
|
||||||
|
continue
|
||||||
|
fn=os.path.join(od,f)
|
||||||
|
os.unlink(f)
|
||||||
|
|
||||||
|
print("#prescript...")
|
||||||
|
prebuild(env)
|
||||||
|
#script does not run on clean yet - maybe in the future
|
||||||
|
env.AddPostAction("clean",cleangenerated)
|
||||||
|
|
|
@ -16,15 +16,12 @@ class EmbeddedFile {
|
||||||
embeddedFiles[name]=this;
|
embeddedFiles[name]=this;
|
||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
#define EMBED_GZ_FILE(fileName, fileExt, contentType) \
|
#define EMBED_GZ_FILE(fileName, binName, contentType) \
|
||||||
extern const uint8_t fileName##_##fileExt##_File[] asm("_binary_generated_" #fileName "_" #fileExt "_gz_start"); \
|
extern const uint8_t binName##_File[] asm("_binary_" #binName "_start"); \
|
||||||
extern const uint8_t fileName##_##fileExt##_FileLen[] asm("_binary_generated_" #fileName "_" #fileExt "_gz_size"); \
|
extern const uint8_t binName##_FileLen[] asm("_binary_" #binName "_size"); \
|
||||||
const EmbeddedFile fileName##_##fileExt##_Config(#fileName "." #fileExt,contentType,(const uint8_t*)fileName##_##fileExt##_File,(int)fileName##_##fileExt##_FileLen);
|
const EmbeddedFile binName##_Config(fileName,contentType,(const uint8_t*)binName##_File,(int)binName##_FileLen);
|
||||||
|
|
||||||
EMBED_GZ_FILE(index,html,"text/html")
|
#include "GwEmbeddedFiles.h"
|
||||||
EMBED_GZ_FILE(config,json,"application/json")
|
|
||||||
EMBED_GZ_FILE(index,js,"text/javascript")
|
|
||||||
EMBED_GZ_FILE(index,css,"text/css")
|
|
||||||
|
|
||||||
void sendEmbeddedFile(String name,String contentType,AsyncWebServerRequest *request){
|
void sendEmbeddedFile(String name,String contentType,AsyncWebServerRequest *request){
|
||||||
std::map<String,EmbeddedFile*>::iterator it=embeddedFiles.find(name);
|
std::map<String,EmbeddedFile*>::iterator it=embeddedFiles.find(name);
|
||||||
|
|
|
@ -23,6 +23,7 @@ board_build.embed_files =
|
||||||
generated/index.js.gz
|
generated/index.js.gz
|
||||||
generated/index.css.gz
|
generated/index.css.gz
|
||||||
generated/config.json.gz
|
generated/config.json.gz
|
||||||
|
generated/xdrconfig.json.gz
|
||||||
board_build.partitions = partitions_custom.csv
|
board_build.partitions = partitions_custom.csv
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
pre:extra_script.py
|
pre:extra_script.py
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
*{
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
body{
|
body{
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +92,58 @@ body{
|
||||||
.hidden{
|
.hidden{
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
#xdrPage .content.hidden {
|
||||||
|
display: unset !important;
|
||||||
|
}
|
||||||
|
#xdrPage .category .title{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#xdrPage span.label{
|
||||||
|
width: 4em;
|
||||||
|
}
|
||||||
|
#xdrPage .value{
|
||||||
|
width: 24em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xdrline {
|
||||||
|
padding-top: 0.2em;
|
||||||
|
padding-bottom: 0.2em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.xdrunused{
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
span.xdrlabel {
|
||||||
|
width: 8em;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.xdrinput .xdrdir {
|
||||||
|
width: 12em;
|
||||||
|
}
|
||||||
|
.xdrinput .xdrdir:before {
|
||||||
|
content: 'Direction';
|
||||||
|
}
|
||||||
|
.xdrinput .xdrcat {
|
||||||
|
width: 12em;
|
||||||
|
}
|
||||||
|
.xdrinput .xdrsel {
|
||||||
|
width: 12em;
|
||||||
|
}
|
||||||
|
.xdrinput .xdrfield {
|
||||||
|
width: 12em;
|
||||||
|
}
|
||||||
|
.xdrinput .xdrimode {
|
||||||
|
width: 8em;
|
||||||
|
}
|
||||||
|
.xdrinput .xdrinstance {
|
||||||
|
width: 4em;
|
||||||
|
}
|
||||||
|
.xdrinput .xdrname {
|
||||||
|
width: 16em;
|
||||||
|
}
|
||||||
.msgDetails .value {
|
.msgDetails .value {
|
||||||
width: 5em;
|
width: 5em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
<div id="tabs">
|
<div id="tabs">
|
||||||
<div class="tab active" data-page="statusPage">Status</div>
|
<div class="tab active" data-page="statusPage">Status</div>
|
||||||
<div class="tab" data-page="configPage">Config</div>
|
<div class="tab" data-page="configPage">Config</div>
|
||||||
|
<div class="tab" data-page="xdrPage">XDR</div>
|
||||||
<div class="tab" data-page="dashboardPage">Data</div>
|
<div class="tab" data-page="dashboardPage">Data</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="statusPage" class="tabPage">
|
<div id="statusPage" class="tabPage">
|
||||||
|
@ -56,6 +57,16 @@
|
||||||
<button id="factoryReset">FactoryReset</button>
|
<button id="factoryReset">FactoryReset</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="configForm tabPage hidden" id="xdrPage" >
|
||||||
|
<div class="configFormRows">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<button id="resetForm">ReloadConfig</button>
|
||||||
|
<button id="changeConfig">Save&Restart</button>
|
||||||
|
<button id="loadUnassigned">Show Unmapped</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="tabPage hidden" id="dashboardPage">
|
<div class="tabPage hidden" id="dashboardPage">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
255
web/index.js
255
web/index.js
|
@ -3,12 +3,14 @@ let lastUpdate = (new Date()).getTime();
|
||||||
let reloadConfig = false;
|
let reloadConfig = false;
|
||||||
function addEl(type, clazz, parent, text) {
|
function addEl(type, clazz, parent, text) {
|
||||||
let el = document.createElement(type);
|
let el = document.createElement(type);
|
||||||
if ( ! (clazz instanceof Array)){
|
if (clazz) {
|
||||||
clazz=clazz.split(/ */);
|
if (!(clazz instanceof Array)) {
|
||||||
|
clazz = clazz.split(/ */);
|
||||||
}
|
}
|
||||||
clazz.forEach(function(ce){
|
clazz.forEach(function (ce) {
|
||||||
el.classList.add(ce);
|
el.classList.add(ce);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
if (text) el.textContent = text;
|
if (text) el.textContent = text;
|
||||||
if (parent) parent.appendChild(el);
|
if (parent) parent.appendChild(el);
|
||||||
return el;
|
return el;
|
||||||
|
@ -230,15 +232,22 @@ function checkChange(el, row) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function createInput(configItem, frame) {
|
let configDefinitions;
|
||||||
|
let xdrConfig;
|
||||||
|
function createInput(configItem, frame,clazz) {
|
||||||
let el;
|
let el;
|
||||||
if (configItem.type === 'boolean' || configItem.type === 'list') {
|
if (configItem.type === 'boolean' || configItem.type === 'list') {
|
||||||
el = document.createElement('select')
|
el=addEl('select',clazz,frame);
|
||||||
el.setAttribute('name', configItem.name)
|
el.setAttribute('name', configItem.name)
|
||||||
let slist = [];
|
let slist = [];
|
||||||
if (configItem.list) {
|
if (configItem.list) {
|
||||||
configItem.list.forEach(function (v) {
|
configItem.list.forEach(function (v) {
|
||||||
|
if (v instanceof Object){
|
||||||
|
slist.push({l:v.l,v:v.v});
|
||||||
|
}
|
||||||
|
else{
|
||||||
slist.push({ l: v, v: v });
|
slist.push({ l: v, v: v });
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -246,17 +255,188 @@ function createInput(configItem, frame) {
|
||||||
slist.push({ l: 'off', v: 'false' })
|
slist.push({ l: 'off', v: 'false' })
|
||||||
}
|
}
|
||||||
slist.forEach(function (sitem) {
|
slist.forEach(function (sitem) {
|
||||||
let sitemEl = document.createElement('option');
|
let sitemEl = addEl('option','',el,sitem.l);
|
||||||
sitemEl.setAttribute('value', sitem.v);
|
sitemEl.setAttribute('value', sitem.v);
|
||||||
sitemEl.textContent = sitem.l;
|
|
||||||
el.appendChild(sitemEl);
|
|
||||||
})
|
})
|
||||||
frame.appendChild(el);
|
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
if (configItem.type === 'filter') {
|
if (configItem.type === 'filter') {
|
||||||
el = document.createElement('div');
|
return createFilterInput(configItem,frame,clazz);
|
||||||
el.classList.add('filter');
|
}
|
||||||
|
if (configItem.type === 'xdr'){
|
||||||
|
return createXdrInput(configItem,frame,clazz);
|
||||||
|
}
|
||||||
|
el = addEl('input',clazz,frame);
|
||||||
|
el.setAttribute('name', configItem.name)
|
||||||
|
if (configItem.type === 'password') {
|
||||||
|
el.setAttribute('type', 'password');
|
||||||
|
let vis = addEl('span', 'icon-eye icon', frame);
|
||||||
|
vis.addEventListener('click', function (v) {
|
||||||
|
if (vis.classList.toggle('active')) {
|
||||||
|
el.setAttribute('type', 'text');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
el.setAttribute('type', 'password');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (configItem.type === 'number') {
|
||||||
|
el.setAttribute('type', 'number');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
el.setAttribute('type', 'text');
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSelectList(item,slist){
|
||||||
|
item.innerHTML='';
|
||||||
|
slist.forEach(function (sitem) {
|
||||||
|
let sitemEl = addEl('option','',item,sitem.l);
|
||||||
|
sitemEl.setAttribute('value', sitem.v);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function getXdrCategories(){
|
||||||
|
let rt=[];
|
||||||
|
for (let c in xdrConfig){
|
||||||
|
if (xdrConfig[c].enabled !== false){
|
||||||
|
rt.push({l:c,v:xdrConfig[c].id});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
function getXdrSelectors(category){
|
||||||
|
category=parseInt(category);
|
||||||
|
for (let c in xdrConfig){
|
||||||
|
let base=xdrConfig[c];
|
||||||
|
if (parseInt(base.id) == category){
|
||||||
|
return base.selector || [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
function getXdrFields(category){
|
||||||
|
category=parseInt(category);
|
||||||
|
for (let c in xdrConfig){
|
||||||
|
let base=xdrConfig[c];
|
||||||
|
if (parseInt(base.id) == category){
|
||||||
|
return base.fields || [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function createXdrLine(parent,label){
|
||||||
|
let d=addEl('div','xdrline',parent);
|
||||||
|
addEl('span','xdrlabel',d,label);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
function showHideXdr(el,show,useParent){
|
||||||
|
if (useParent) el=el.parentElement;
|
||||||
|
if (show) el.classList.remove('xdrunused');
|
||||||
|
else el.classList.add('xdrunused');
|
||||||
|
}
|
||||||
|
|
||||||
|
function createXdrInput(configItem,frame){
|
||||||
|
let el = addEl('div','xdrinput',frame);
|
||||||
|
let d=createXdrLine(el,'Direction');
|
||||||
|
let direction=createInput({
|
||||||
|
type:'list',
|
||||||
|
name: configItem.name+"_dir",
|
||||||
|
list: [
|
||||||
|
//GwXDRMappingDef::Direction
|
||||||
|
{l:'off',v:0},
|
||||||
|
{l:'bidir',v:1},
|
||||||
|
{l:'to2K',v:2},
|
||||||
|
{l:'from2K',v:3}
|
||||||
|
]
|
||||||
|
},d,'xdrdir');
|
||||||
|
d=createXdrLine(el,'Category');
|
||||||
|
let category=createInput({
|
||||||
|
type: 'list',
|
||||||
|
name: configItem.name+"_cat",
|
||||||
|
list:getXdrCategories()
|
||||||
|
},d,'xdrcat');
|
||||||
|
d=createXdrLine(el,'Source');
|
||||||
|
let selector=createInput({
|
||||||
|
type: 'list',
|
||||||
|
name: configItem.name+"_sel",
|
||||||
|
list:[]
|
||||||
|
},d,'xdrsel');
|
||||||
|
d=createXdrLine(el,'Field');
|
||||||
|
let field=createInput({
|
||||||
|
type:'list',
|
||||||
|
name: configItem.name+'_field',
|
||||||
|
list: []
|
||||||
|
},d,'xdrfield');
|
||||||
|
d=createXdrLine(el,'Instance');
|
||||||
|
let imode=createInput({
|
||||||
|
type:'list',
|
||||||
|
name: configItem.name+"_imode",
|
||||||
|
list:[
|
||||||
|
//GwXDRMappingDef::InstanceMode
|
||||||
|
{l:'single',v:0},
|
||||||
|
{l:'ignore',v:1},
|
||||||
|
{l:'auto',v:2}
|
||||||
|
]
|
||||||
|
},d,'xdrimode');
|
||||||
|
let instance=createInput({
|
||||||
|
type:'number',
|
||||||
|
name: configItem.name+"_instance",
|
||||||
|
},d,'xdrinstance');
|
||||||
|
d=createXdrLine(el,'Transducer');
|
||||||
|
let xdrName=createInput({
|
||||||
|
type:'text',
|
||||||
|
name: configItem.name+"_xdr"
|
||||||
|
},d,'xdrname');
|
||||||
|
let data = addEl('input',undefined,el);
|
||||||
|
data.setAttribute('type', 'hidden');
|
||||||
|
data.setAttribute('name', configItem.name);
|
||||||
|
let changeFunction = function () {
|
||||||
|
let parts=data.value.split(',');
|
||||||
|
direction.value=parts[1] || 0;
|
||||||
|
category.value=parts[0] || 0;
|
||||||
|
let selectors=getXdrSelectors(category.value);
|
||||||
|
updateSelectList(selector,selectors);
|
||||||
|
showHideXdr(selector,selectors.length>0);
|
||||||
|
let fields=getXdrFields(category.value);
|
||||||
|
updateSelectList(field,fields);
|
||||||
|
showHideXdr(field,fields.length>0);
|
||||||
|
selector.value=parts[2]||0;
|
||||||
|
field.value=parts[3]||0;
|
||||||
|
imode.value=parts[4]||0;
|
||||||
|
instance.value=parts[5]||0;
|
||||||
|
showHideXdr(instance,imode.value == 0);
|
||||||
|
xdrName.value=parts[6]||'';
|
||||||
|
}
|
||||||
|
let updateFunction = function () {
|
||||||
|
let txt=category.value+","+direction.value+","+
|
||||||
|
selector.value+","+field.value+","+imode.value;
|
||||||
|
let instanceValue=parseInt(instance.value||0);
|
||||||
|
if (isNaN(instanceValue)) instanceValue=0;
|
||||||
|
if (instanceValue<0) instanceValue=0;
|
||||||
|
if (instanceValue>255) instanceValue=255;
|
||||||
|
txt+=","+instanceValue;
|
||||||
|
let xdr=xdrName.value.replace(/[^a-zA-Z0-9]/g,'');
|
||||||
|
xdr=xdr.substr(0,12);
|
||||||
|
txt+=","+xdr;
|
||||||
|
data.value=txt;
|
||||||
|
let ev=new Event('change');
|
||||||
|
data.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
category.addEventListener('change',updateFunction);
|
||||||
|
direction.addEventListener('change',updateFunction);
|
||||||
|
selector.addEventListener('change',updateFunction);
|
||||||
|
field.addEventListener('change',updateFunction);
|
||||||
|
imode.addEventListener('change',updateFunction);
|
||||||
|
instance.addEventListener('change',updateFunction);
|
||||||
|
xdrName.addEventListener('change',updateFunction);
|
||||||
|
data.addEventListener('change',changeFunction);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFilterInput(configItem, frame) {
|
||||||
|
let el = addEl('div','filter',frame);
|
||||||
let ais = createInput({
|
let ais = createInput({
|
||||||
type: 'list',
|
type: 'list',
|
||||||
name: configItem.name + "_ais",
|
name: configItem.name + "_ais",
|
||||||
|
@ -271,9 +451,8 @@ function createInput(configItem, frame) {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: configItem.name + "_sentences",
|
name: configItem.name + "_sentences",
|
||||||
}, el);
|
}, el);
|
||||||
let data = document.createElement('input');
|
let data = addEl('input',undefined,el);
|
||||||
data.setAttribute('type', 'hidden');
|
data.setAttribute('type', 'hidden');
|
||||||
el.appendChild(data);
|
|
||||||
let changeFunction = function () {
|
let changeFunction = function () {
|
||||||
let cv = data.value || "";
|
let cv = data.value || "";
|
||||||
let parts = cv.split(":");
|
let parts = cv.split(":");
|
||||||
|
@ -298,46 +477,19 @@ function createInput(configItem, frame) {
|
||||||
changeFunction();
|
changeFunction();
|
||||||
});
|
});
|
||||||
data.setAttribute('name', configItem.name);
|
data.setAttribute('name', configItem.name);
|
||||||
frame.appendChild(el);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
|
||||||
el = document.createElement('input');
|
|
||||||
el.setAttribute('name', configItem.name)
|
|
||||||
frame.appendChild(el);
|
|
||||||
if (configItem.type === 'password') {
|
|
||||||
el.setAttribute('type', 'password');
|
|
||||||
let vis = addEl('span', 'icon-eye icon', frame);
|
|
||||||
vis.addEventListener('click', function (v) {
|
|
||||||
if (vis.classList.toggle('active')) {
|
|
||||||
el.setAttribute('type', 'text');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
el.setAttribute('type', 'password');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (configItem.type === 'number') {
|
|
||||||
el.setAttribute('type', 'number');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
el.setAttribute('type', 'text');
|
|
||||||
}
|
|
||||||
return el;
|
|
||||||
}
|
}
|
||||||
let configDefinitions;
|
|
||||||
function loadConfigDefinitions() {
|
function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
||||||
getJson("api/capabilities")
|
|
||||||
.then(function (capabilities) {
|
|
||||||
getJson("config.json")
|
|
||||||
.then(function (defs) {
|
|
||||||
let category;
|
let category;
|
||||||
let categoryEl;
|
let categoryEl;
|
||||||
let frame = document.querySelector('.configFormRows');
|
let frame = parent.querySelector('.configFormRows');
|
||||||
if (!frame) throw Error("no config form");
|
if (!frame) throw Error("no config form");
|
||||||
frame.innerHTML = '';
|
frame.innerHTML = '';
|
||||||
configDefinitions = defs;
|
configDefinitions = defs;
|
||||||
defs.forEach(function (item) {
|
defs.forEach(function (item) {
|
||||||
if (!item.type) return;
|
if (!item.type) return;
|
||||||
|
if ((item.category === 'xdr') !== includeXdr) return;
|
||||||
if (item.category != category || !categoryEl) {
|
if (item.category != category || !categoryEl) {
|
||||||
let categoryFrame = addEl('div', 'category', frame);
|
let categoryFrame = addEl('div', 'category', frame);
|
||||||
let categoryTitle = addEl('div', 'title', categoryFrame);
|
let categoryTitle = addEl('div', 'title', categoryFrame);
|
||||||
|
@ -395,9 +547,24 @@ function loadConfigDefinitions() {
|
||||||
showOverlay(item.description);
|
showOverlay(item.description);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
function loadConfigDefinitions() {
|
||||||
|
getJson("api/capabilities")
|
||||||
|
.then(function (capabilities) {
|
||||||
|
getJson("config.json")
|
||||||
|
.then(function (defs) {
|
||||||
|
getJson("xdrconfig.json")
|
||||||
|
.then(function(xdr){
|
||||||
|
xdrConfig=xdr;
|
||||||
|
configDefinitions=defs;
|
||||||
|
let normalConfig=document.getElementById('configPage');
|
||||||
|
let xdrParent=document.getElementById('xdrPage');
|
||||||
|
if (normalConfig) createConfigDefinitions(normalConfig,capabilities,defs,false);
|
||||||
|
if (xdrParent) createConfigDefinitions(xdrParent,capabilities,defs,true);
|
||||||
resetForm();
|
resetForm();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
})
|
||||||
.catch(function (err) { alert("unable to load config: " + err) })
|
.catch(function (err) { alert("unable to load config: " + err) })
|
||||||
}
|
}
|
||||||
function converterInfo() {
|
function converterInfo() {
|
||||||
|
|
Loading…
Reference in New Issue