Merge branch 'master' into sensors
This commit is contained in:
commit
f9a001a9c2
|
@ -71,9 +71,12 @@ class GwConverterConfig{
|
||||||
int rmcInterval=1000;
|
int rmcInterval=1000;
|
||||||
int rmcCheckTime=4000;
|
int rmcCheckTime=4000;
|
||||||
int winst312=256;
|
int winst312=256;
|
||||||
|
bool unmappedXdr=false;
|
||||||
|
unsigned long xdrTimeout=60000;
|
||||||
std::vector<WindMapping> windMappings;
|
std::vector<WindMapping> windMappings;
|
||||||
void init(GwConfigHandler *config, GwLog*logger){
|
void init(GwConfigHandler *config, GwLog*logger){
|
||||||
minXdrInterval=config->getInt(GwConfigDefinitions::minXdrInterval,100);
|
minXdrInterval=config->getInt(GwConfigDefinitions::minXdrInterval,100);
|
||||||
|
xdrTimeout=config->getInt(GwConfigDefinitions::timoSensor);
|
||||||
starboardRudderInstance=config->getInt(GwConfigDefinitions::stbRudderI,0);
|
starboardRudderInstance=config->getInt(GwConfigDefinitions::stbRudderI,0);
|
||||||
portRudderInstance=config->getInt(GwConfigDefinitions::portRudderI,-1);
|
portRudderInstance=config->getInt(GwConfigDefinitions::portRudderI,-1);
|
||||||
min2KInterval=config->getInt(GwConfigDefinitions::min2KInterval,50);
|
min2KInterval=config->getInt(GwConfigDefinitions::min2KInterval,50);
|
||||||
|
@ -83,6 +86,7 @@ class GwConverterConfig{
|
||||||
rmcInterval=config->getInt(GwConfigDefinitions::sendRMCi,1000);
|
rmcInterval=config->getInt(GwConfigDefinitions::sendRMCi,1000);
|
||||||
if (rmcInterval < 0) rmcInterval=0;
|
if (rmcInterval < 0) rmcInterval=0;
|
||||||
if (rmcInterval > 0 && rmcInterval <100) rmcInterval=100;
|
if (rmcInterval > 0 && rmcInterval <100) rmcInterval=100;
|
||||||
|
unmappedXdr=config->getBool(GwConfigDefinitions::unknownXdr);
|
||||||
winst312=config->getInt(GwConfigDefinitions::winst312,256);
|
winst312=config->getInt(GwConfigDefinitions::winst312,256);
|
||||||
for (auto && it:windConfigs){
|
for (auto && it:windConfigs){
|
||||||
String cfg=config->getString(it.second);
|
String cfg=config->getString(it.second);
|
||||||
|
|
|
@ -108,7 +108,7 @@ void GwWifi::loop(){
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (! clientIsConnected){
|
if (! clientIsConnected){
|
||||||
LOG_DEBUG(GwLog::LOG,"wifiClient %s now connected to",wifiSSID->asCString());
|
LOG_DEBUG(GwLog::LOG,"wifiClient now connected to %s at %s",wifiSSID->asCString(),WiFi.localIP().toString().c_str());
|
||||||
clientIsConnected=true;
|
clientIsConnected=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,6 +189,7 @@ private:
|
||||||
if (N2kIsNA(v)) return N2kInt8NA;
|
if (N2kIsNA(v)) return N2kInt8NA;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void convertXDR(const SNMEA0183Msg &msg){
|
void convertXDR(const SNMEA0183Msg &msg){
|
||||||
XdrMappingList foundMappings;
|
XdrMappingList foundMappings;
|
||||||
for (int offset=0;offset <= (msg.FieldCount()-4);offset+=4){
|
for (int offset=0;offset <= (msg.FieldCount()-4);offset+=4){
|
||||||
|
@ -199,7 +200,19 @@ private:
|
||||||
String unit=msg.Field(offset+2);
|
String unit=msg.Field(offset+2);
|
||||||
String transducerName=msg.Field(offset+3);
|
String transducerName=msg.Field(offset+3);
|
||||||
GwXDRFoundMapping found=xdrMappings->getMapping(transducerName,type,unit);
|
GwXDRFoundMapping found=xdrMappings->getMapping(transducerName,type,unit);
|
||||||
if (found.empty) continue;
|
if (found.empty) {
|
||||||
|
if (config.unmappedXdr){
|
||||||
|
const GwXDRType *typeDef=xdrMappings->findType(type,unit);
|
||||||
|
GwXdrUnknownMapping mapping(transducerName,unit,typeDef,config.xdrTimeout);
|
||||||
|
value=mapping.valueFromXdr(value);
|
||||||
|
if (boatData->update(value,msg.sourceId,&mapping)){
|
||||||
|
//TODO: potentially update the format
|
||||||
|
LOG_DEBUG(GwLog::DEBUG+1,"found unmapped XDR %s:%s, value %f",
|
||||||
|
transducerName.c_str(),mapping.getBoatItemFormat().c_str(),value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
value=found.valueFromXdr(value);
|
value=found.valueFromXdr(value);
|
||||||
if (!boatData->update(value,msg.sourceId,&found)) continue;
|
if (!boatData->update(value,msg.sourceId,&found)) continue;
|
||||||
LOG_DEBUG(GwLog::DEBUG+1,"found mapped XDR %s:%s, value %f",
|
LOG_DEBUG(GwLog::DEBUG+1,"found mapped XDR %s:%s, value %f",
|
||||||
|
@ -307,7 +320,7 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tN2kMsg n2kMsg;
|
tN2kMsg n2kMsg;
|
||||||
if (boatData->XTE->update(rmb.xte,msg.sourceId)){
|
if (updateDouble(boatData->XTE,rmb.xte,msg.sourceId)){
|
||||||
tN2kXTEMode mode=N2kxtem_Autonomous;
|
tN2kXTEMode mode=N2kxtem_Autonomous;
|
||||||
if (msg.FieldCount() > 13){
|
if (msg.FieldCount() > 13){
|
||||||
const char *modeChar=msg.Field(13);
|
const char *modeChar=msg.Field(13);
|
||||||
|
@ -318,10 +331,10 @@ private:
|
||||||
}
|
}
|
||||||
uint8_t destinationId=getWaypointId(rmb.destID);
|
uint8_t destinationId=getWaypointId(rmb.destID);
|
||||||
uint8_t sourceId=getWaypointId(rmb.originID);
|
uint8_t sourceId=getWaypointId(rmb.originID);
|
||||||
if (boatData->DTW->update(rmb.dtw,msg.sourceId)
|
if (updateDouble(boatData->DTW,rmb.dtw,msg.sourceId)
|
||||||
&& boatData->BTW->update(rmb.btw,msg.sourceId)
|
&& updateDouble(boatData->BTW,rmb.btw,msg.sourceId)
|
||||||
&& boatData->WPLat->update(rmb.latitude,msg.sourceId)
|
&& updateDouble(boatData->WPLat,rmb.latitude,msg.sourceId)
|
||||||
&& boatData->WPLon->update(rmb.longitude,msg.sourceId)
|
&& updateDouble(boatData->WPLon,rmb.longitude,msg.sourceId)
|
||||||
){
|
){
|
||||||
SetN2kNavigationInfo(n2kMsg,1,rmb.dtw,N2khr_true,
|
SetN2kNavigationInfo(n2kMsg,1,rmb.dtw,N2khr_true,
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -90,6 +90,7 @@ class TaskInterfacesStorage{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
GwApi::TaskInterfaces::Ptr get(const String &name, int &result){
|
GwApi::TaskInterfaces::Ptr get(const String &name, int &result){
|
||||||
|
GWSYNCHRONIZED(lock);
|
||||||
GWSYNCHRONIZED(lock);
|
GWSYNCHRONIZED(lock);
|
||||||
auto it = values.find(name);
|
auto it = values.find(name);
|
||||||
if (it == values.end())
|
if (it == values.end())
|
||||||
|
@ -161,6 +162,7 @@ class TaskApi : public GwApiInternal
|
||||||
GwApiInternal *api=nullptr;
|
GwApiInternal *api=nullptr;
|
||||||
int sourceId;
|
int sourceId;
|
||||||
SemaphoreHandle_t mainLock;
|
SemaphoreHandle_t mainLock;
|
||||||
|
SemaphoreHandle_t mainLock;
|
||||||
SemaphoreHandle_t localLock;
|
SemaphoreHandle_t localLock;
|
||||||
std::map<int,GwCounter<String>> counter;
|
std::map<int,GwCounter<String>> counter;
|
||||||
std::map<String,GwApi::HandlerFunction> webHandlers;
|
std::map<String,GwApi::HandlerFunction> webHandlers;
|
||||||
|
@ -243,6 +245,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
virtual int getJsonSize(){
|
virtual int getJsonSize(){
|
||||||
|
GWSYNCHRONIZED(localLock);
|
||||||
GWSYNCHRONIZED(localLock);
|
GWSYNCHRONIZED(localLock);
|
||||||
if (! counterUsed) return 0;
|
if (! counterUsed) return 0;
|
||||||
int rt=0;
|
int rt=0;
|
||||||
|
@ -252,6 +255,7 @@ public:
|
||||||
return rt;
|
return rt;
|
||||||
};
|
};
|
||||||
virtual void increment(int idx,const String &name,bool failed=false){
|
virtual void increment(int idx,const String &name,bool failed=false){
|
||||||
|
GWSYNCHRONIZED(localLock);
|
||||||
GWSYNCHRONIZED(localLock);
|
GWSYNCHRONIZED(localLock);
|
||||||
counterUsed=true;
|
counterUsed=true;
|
||||||
auto it=counter.find(idx);
|
auto it=counter.find(idx);
|
||||||
|
|
|
@ -58,6 +58,7 @@ GwXDRType *types[] = {
|
||||||
new GwXDRType(GwXDRType::DISPLACEMENTD, "A", "D",DegToRad,RadToDeg,"rd"),
|
new GwXDRType(GwXDRType::DISPLACEMENTD, "A", "D",DegToRad,RadToDeg,"rd"),
|
||||||
new GwXDRType(GwXDRType::RPM,"T","R")
|
new GwXDRType(GwXDRType::RPM,"T","R")
|
||||||
};
|
};
|
||||||
|
static GwXDRType genericType(GwXDRType::GENERIC, "G", "");
|
||||||
template<typename T, int size>
|
template<typename T, int size>
|
||||||
int GetArrLength(T(&)[size]){return size;}
|
int GetArrLength(T(&)[size]){return size;}
|
||||||
static GwXDRType *findType(GwXDRType::TypeCode type, int *start = NULL)
|
static GwXDRType *findType(GwXDRType::TypeCode type, int *start = NULL)
|
||||||
|
@ -82,6 +83,19 @@ static GwXDRType *findType(GwXDRType::TypeCode type, int *start = NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GwXDRType *findType(const String &typeString, const String &unitString)
|
||||||
|
{
|
||||||
|
int len=GetArrLength(types);
|
||||||
|
for (int i=0; i< len; i++)
|
||||||
|
{
|
||||||
|
if (types[i]->xdrtype == typeString && types[i]->xdrunit == unitString)
|
||||||
|
{
|
||||||
|
return types[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &genericType;
|
||||||
|
}
|
||||||
|
|
||||||
#include "GwXdrTypeMappings.h"
|
#include "GwXdrTypeMappings.h"
|
||||||
|
|
||||||
static GwXDRType::TypeCode findTypeMapping(GwXDRCategory category, int field)
|
static GwXDRType::TypeCode findTypeMapping(GwXDRCategory category, int field)
|
||||||
|
@ -199,7 +213,7 @@ GwXDRMappingDef *GwXDRMappingDef::fromString(String s)
|
||||||
}
|
}
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
String GwXDRMappingDef::getTransducerName(int instance)
|
String GwXDRMappingDef::getTransducerName(int instance) const
|
||||||
{
|
{
|
||||||
String name = xdrName;
|
String name = xdrName;
|
||||||
if (instanceMode == GwXDRMappingDef::IS_AUTO)
|
if (instanceMode == GwXDRMappingDef::IS_AUTO)
|
||||||
|
@ -257,7 +271,7 @@ bool GwXDRMappings::addMapping(GwXDRMappingDef *def)
|
||||||
LOG_DEBUG(GwLog::ERROR, "no type mapping for %s", def->toString().c_str());
|
LOG_DEBUG(GwLog::ERROR, "no type mapping for %s", def->toString().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
GwXDRType *type = findType(code, &typeIndex);
|
GwXDRType *type = ::findType(code, &typeIndex);
|
||||||
if (!type)
|
if (!type)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(GwLog::ERROR, "no type definition for %s", def->toString().c_str());
|
LOG_DEBUG(GwLog::ERROR, "no type definition for %s", def->toString().c_str());
|
||||||
|
@ -298,7 +312,7 @@ bool GwXDRMappings::addMapping(GwXDRMappingDef *def)
|
||||||
LOG_DEBUG(GwLog::LOG, "append mapping with n183key %s", n183key.c_str());
|
LOG_DEBUG(GwLog::LOG, "append mapping with n183key %s", n183key.c_str());
|
||||||
it->second.push_back(mapping);
|
it->second.push_back(mapping);
|
||||||
}
|
}
|
||||||
type = findType(code, &typeIndex);
|
type = ::findType(code, &typeIndex);
|
||||||
if (!type)
|
if (!type)
|
||||||
break;
|
break;
|
||||||
mapping = new GwXDRMapping(def, type);
|
mapping = new GwXDRMapping(def, type);
|
||||||
|
@ -471,7 +485,7 @@ String GwXDRMappings::getXdrEntry(String mapping, double value,int instance){
|
||||||
{
|
{
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
GwXDRType *type = findType(code, &typeIndex);
|
GwXDRType *type = ::findType(code, &typeIndex);
|
||||||
bool first=true;
|
bool first=true;
|
||||||
unsigned long invalidTime=config->getInt(GwConfigDefinitions::timoSensor);
|
unsigned long invalidTime=config->getInt(GwConfigDefinitions::timoSensor);
|
||||||
while (type){
|
while (type){
|
||||||
|
@ -480,8 +494,12 @@ String GwXDRMappings::getXdrEntry(String mapping, double value,int instance){
|
||||||
if (first) first=false;
|
if (first) first=false;
|
||||||
else rt+=",";
|
else rt+=",";
|
||||||
rt+=found.buildXdrEntry(value).entry;
|
rt+=found.buildXdrEntry(value).entry;
|
||||||
type = findType(code, &typeIndex);
|
type = ::findType(code, &typeIndex);
|
||||||
}
|
}
|
||||||
delete def;
|
delete def;
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GwXDRType * GwXDRMappings::findType(const String &typeString, const String &unitString) const{
|
||||||
|
return ::findType(typeString,unitString);
|
||||||
|
}
|
|
@ -140,7 +140,7 @@ class GwXDRMappingDef{
|
||||||
rt += xdrUnit;
|
rt += xdrUnit;
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
String getTransducerName(int instance);
|
String getTransducerName(int instance) const;
|
||||||
private:
|
private:
|
||||||
static bool handleToken(String tok,int index,GwXDRMappingDef *def);
|
static bool handleToken(String tok,int index,GwXDRMappingDef *def);
|
||||||
};
|
};
|
||||||
|
@ -163,12 +163,12 @@ class GwXDRFoundMapping : public GwBoatItemNameProvider{
|
||||||
String entry;
|
String entry;
|
||||||
String transducer;
|
String transducer;
|
||||||
};
|
};
|
||||||
GwXDRMappingDef *definition=NULL;
|
const GwXDRMappingDef *definition=NULL;
|
||||||
GwXDRType *type=NULL;
|
const GwXDRType *type=NULL;
|
||||||
int instanceId=-1;
|
int instanceId=-1;
|
||||||
bool empty=true;
|
bool empty=true;
|
||||||
unsigned long timeout=0;
|
unsigned long timeout=0;
|
||||||
GwXDRFoundMapping(GwXDRMappingDef *definition,GwXDRType *type, unsigned long timeout){
|
GwXDRFoundMapping(const GwXDRMappingDef *definition,const GwXDRType *type, unsigned long timeout){
|
||||||
this->definition=definition;
|
this->definition=definition;
|
||||||
this->type=type;
|
this->type=type;
|
||||||
this->timeout=timeout;
|
this->timeout=timeout;
|
||||||
|
@ -182,7 +182,7 @@ class GwXDRFoundMapping : public GwBoatItemNameProvider{
|
||||||
empty=false;
|
empty=false;
|
||||||
}
|
}
|
||||||
GwXDRFoundMapping(){}
|
GwXDRFoundMapping(){}
|
||||||
String getTransducerName(){
|
virtual String getTransducerName(){
|
||||||
return definition->getTransducerName(instanceId);
|
return definition->getTransducerName(instanceId);
|
||||||
}
|
}
|
||||||
double valueFromXdr(double value){
|
double valueFromXdr(double value){
|
||||||
|
@ -203,6 +203,24 @@ class GwXDRFoundMapping : public GwBoatItemNameProvider{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GwXdrUnknownMapping : public GwXDRFoundMapping{
|
||||||
|
String name;
|
||||||
|
String unit;
|
||||||
|
public:
|
||||||
|
GwXdrUnknownMapping(const String &xdrName, const String &xdrUnit,const GwXDRType *type,unsigned long timeout):
|
||||||
|
name(xdrName),unit(xdrUnit), GwXDRFoundMapping(nullptr,type,timeout){
|
||||||
|
|
||||||
|
}
|
||||||
|
virtual String getTransducerName(){
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
virtual String getBoatItemFormat(){
|
||||||
|
String rt=GwXDRFoundMapping::getBoatItemFormat();
|
||||||
|
if (type->xdrunit.isEmpty()) rt+=unit;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//the class GwXDRMappings is not intended to be deleted
|
//the class GwXDRMappings is not intended to be deleted
|
||||||
//the deletion will leave memory leaks!
|
//the deletion will leave memory leaks!
|
||||||
class GwConfigHandler;
|
class GwConfigHandler;
|
||||||
|
@ -229,6 +247,7 @@ class GwXDRMappings{
|
||||||
GwXDRFoundMapping getMapping(GwXDRCategory category,int selector,int field=0,int instance=-1);
|
GwXDRFoundMapping getMapping(GwXDRCategory category,int selector,int field=0,int instance=-1);
|
||||||
String getXdrEntry(String mapping, double value,int instance=0);
|
String getXdrEntry(String mapping, double value,int instance=0);
|
||||||
const char * getUnMapped();
|
const char * getUnMapped();
|
||||||
|
const GwXDRType * findType(const String &typeString, const String &unitString) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -209,6 +209,14 @@
|
||||||
"default":"true",
|
"default":"true",
|
||||||
"description":"send out the converted data on the NMEA2000 bus\nIf set to off the converted data will still be shown at the data tab.",
|
"description":"send out the converted data on the NMEA2000 bus\nIf set to off the converted data will still be shown at the data tab.",
|
||||||
"category":"converter"
|
"category":"converter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"unknownXdr",
|
||||||
|
"label":"show unknown XDR",
|
||||||
|
"type":"boolean",
|
||||||
|
"default":"false",
|
||||||
|
"description":"show received XDR transducer values in data display if there is no XDR mapping for them",
|
||||||
|
"category":"converter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name":"sendRMCi",
|
"name":"sendRMCi",
|
||||||
|
|
|
@ -1578,7 +1578,7 @@
|
||||||
if (isNaN(x)) return '-----';
|
if (isNaN(x)) return '-----';
|
||||||
return formatLonLatsDecimal(x, 'lat');
|
return formatLonLatsDecimal(x, 'lat');
|
||||||
},
|
},
|
||||||
u: '°'
|
u: ''
|
||||||
},
|
},
|
||||||
formatLongitude: {
|
formatLongitude: {
|
||||||
f: function (v) {
|
f: function (v) {
|
||||||
|
@ -1798,7 +1798,7 @@
|
||||||
let id = el.getAttribute('id');
|
let id = el.getAttribute('id');
|
||||||
if (id) {
|
if (id) {
|
||||||
if (!names[id.replace(/^frame_/, '')]) {
|
if (!names[id.replace(/^frame_/, '')]) {
|
||||||
el.parentElement.remove();
|
el.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue