diff --git a/lib/obp60task/OBPDataOperations.cpp b/lib/obp60task/OBPDataOperations.cpp index 3834fba..3099536 100644 --- a/lib/obp60task/OBPDataOperations.cpp +++ b/lib/obp60task/OBPDataOperations.cpp @@ -223,14 +223,13 @@ HstryBuf::HstryBuf(const String& name, int size, BoatValueList* boatValues, GwLo boatValue = boatValues->findValueOrCreate(name); } -void HstryBuf::init(const String& format, int updFreq, int mltplr, double minVal, double maxVal) +void HstryBuf::init(const String& format, int updFreq, double mltplr, double minVal, double maxVal) { hstryBuf.setMetaData(boatDataName, format, updFreq, mltplr, minVal, maxVal); hstryMin = minVal; hstryMax = maxVal; bufUpdateTime = 0; if (!boatValue->valid) { - boatValue->setFormat(format); boatValue->value = std::numeric_limits::max(); // mark current value invalid } } @@ -239,15 +238,17 @@ void HstryBuf::add(double value) { if (value >= hstryMin && value <= hstryMax) { hstryBuf.add(value); - // LOG_DEBUG(GwLog::DEBUG, "HstryBuf::add: name: %s, value: %.3f", hstryBuf.getName(), value); + LOG_DEBUG(GwLog::DEBUG, "HstryBuf::add: name: %s, value: %.3f", hstryBuf.getName(), value); } } void HstryBuf::handle(bool useSimuData, CommonData& common) { - if (millis() >= (bufUpdateTime + hstryBuf.getUpdFreq())) { + if ((millis() - bufUpdateTime) >= hstryBuf.getUpdFreq()) { + bufUpdateTime = millis(); - LOG_DEBUG(GwLog::DEBUG, "HstryBuf::handle: name: %s, frequency: %d, bufUpdateTime: %d, value: %.3f", hstryBuf.getName(), hstryBuf.getUpdFreq(), bufUpdateTime, boatValue->value); + // LOG_DEBUG(GwLog::DEBUG, "HstryBuf::handle: name: %s, frequency: %d, format: %s, value: %.3f", hstryBuf.getName(), hstryBuf.getUpdFreq(), + // boatValue->getFormat().c_str(), boatValue->value); if (boatValue->valid) { add(boatValue->value); @@ -279,22 +280,16 @@ void HstryBuffers::addBuffer(const String& name) if (HstryBuffers::getBuffer(name) != nullptr) { // buffer for this data type already exists return; } - if (bufferParams.find(name) == bufferParams.end()) { // requested boat data type is not supported in list of + + auto it = bufferParams.find(name); + if (it == bufferParams.end() && !name.startsWith("xdr")) { // requested boat data type is not supported in list of + // we take any "XDR" type, though return; } - // Initialize metadata for buffer - String valueFormat = bufferParams[name].format; // Data format of boat data type - // String valueFormat = boatValueList->findValueOrCreate(name)->getFormat().c_str(); // Unfortunately, format is not yet available during system initialization - int hstryUpdFreq = bufferParams[name].hstryUpdFreq; // Update frequency for history buffers in ms - int mltplr = bufferParams[name].mltplr; // default multiplier which transforms original value into buffer type format - double bufferMinVal = bufferParams[name].bufferMinVal; // Min value for this history buffer - double bufferMaxVal = bufferParams[name].bufferMaxVal; // Max value for this history buffer - + // create buffer only; initialization with metadata can only be done later after boat data have been updated first time hstryBuffers[name] = std::unique_ptr(new HstryBuf(name, size, boatValueList, logger)); - hstryBuffers[name]->init(valueFormat, hstryUpdFreq, mltplr, bufferMinVal, bufferMaxVal); - LOG_DEBUG(GwLog::DEBUG, "HstryBuffers: new buffer added: name: %s, format: %s, frequency: %d, multiplier: %d, min value: %.2f, max value: %.2f", name, valueFormat, hstryUpdFreq, - mltplr, bufferMinVal, bufferMaxVal); + LOG_DEBUG(GwLog::DEBUG, "HstryBuffers: new buffer added: name: %s", name); } // Handle all registered history buffers @@ -302,6 +297,35 @@ void HstryBuffers::handleHstryBufs(bool useSimuData, CommonData& common) { for (auto& bufMap : hstryBuffers) { auto& buf = bufMap.second; + + if (!buf->hasMetaData()) { // meta data initialization for buffer has not been done before + + String valueFormat = boatValueList->findValueOrCreate(buf->boatDataName)->getFormat().c_str(); + LOG_DEBUG(GwLog::DEBUG, "HstryBuffers: value name: %s, format: %s", boatValueList->findValueOrCreate(buf->boatDataName)->getName().c_str(), valueFormat); + + if (!valueFormat.isEmpty()) { + String lookupKey = buf->boatDataName; + if (buf->boatDataName.startsWith("xdr")) { // current boat data is of type "XDR" + lookupKey = valueFormat; + } + auto it = bufferParams.find(lookupKey); + if (it == bufferParams.end()) { // requested boat data type is not supported in list of + return; + } + HistoryParams params = it->second; // this is the metadata for the new buffer + + int hstryUpdFreq = params.hstryUpdFreq; // Update frequency for history buffers in ms + double mltplr = params.mltplr; // default multiplier which transforms original value into buffer type format + double bufferMinVal = params.bufferMinVal; // Min value for this history buffer + double bufferMaxVal = params.bufferMaxVal; // Max value for this history buffer + + hstryBuffers[buf->boatDataName]->init(valueFormat, hstryUpdFreq, mltplr, bufferMinVal, bufferMaxVal); + buf->metaDataDefined = true; + LOG_DEBUG(GwLog::DEBUG, "HstryBuffers::handleBufs: metadata added: name: %s, format: %s, frequency: %d, multiplier: %f, min value: %.2f, max value: %.2f", buf->boatDataName, valueFormat, hstryUpdFreq, + mltplr, bufferMinVal, bufferMaxVal); + } + } + buf->handle(useSimuData, common); } } diff --git a/lib/obp60task/OBPDataOperations.h b/lib/obp60task/OBPDataOperations.h index ee44f0b..7e48297 100644 --- a/lib/obp60task/OBPDataOperations.h +++ b/lib/obp60task/OBPDataOperations.h @@ -39,6 +39,7 @@ private: String boatDataName; double hstryMin; double hstryMax; + bool metaDataDefined = false; unsigned long bufUpdateTime; GwApi::BoatValue* boatValue; GwLog* logger; @@ -47,7 +48,8 @@ private: public: HstryBuf(const String& name, int size, BoatValueList* boatValues, GwLog* log); - void init(const String& format, int updFreq, int mltplr, double minVal, double maxVal); + bool hasMetaData() const { return metaDataDefined; }; + void init(const String& format, int updFreq, double mltplr, double minVal, double maxVal); void add(double value); void handle(bool useSimuData, CommonData& common); }; @@ -62,33 +64,41 @@ private: struct HistoryParams { int hstryUpdFreq; // update frequency of history buffer (documentation only) - int mltplr; // specifies actual value precision being storable: - // [10000: 0 - 6.5535 | 1000: 0 - 65.535 | 100: 0 - 655.35 | 10: 0 - 6553.5 | 1: 0 - 65535] + double mltplr; // specifies actual value precision being storable: + // [10000: 0 - 6.5535 | 1000: 0 - 65.535 | 100: 0 - 655.35 | 10: 0 - 6553.5 | 1: 0 - 65535 | 0.1: 0 - 655350] double bufferMinVal; // minimum valid data value double bufferMaxVal; // maximum valid data value - String format; // format of data type + //String format; // format of data type }; - // Define buffer parameters for supported boat data type - // Structure: name, frequency, multiplier, minVal, maxVal, format std::map bufferParams = { - { "AWA", { 1000, 10000, 0.0, M_TWOPI, "formatWind" } }, - { "AWD", { 1000, 10000, 0.0, M_TWOPI, "formatCourse" } }, - { "AWS", { 1000, 1000, 0.0, 65.0, "formatKnots" } }, - { "BARO", {60000, 10, 0.0, 6553, "formatXdr:P:B"}}, - { "COG", { 1000, 10000, 0.0, M_TWOPI, "formatCourse" } }, - { "DBS", { 1000, 100, 0.0, 650.0, "formatDepth" } }, - { "DBT", { 1000, 100, 0.0, 650.0, "formatDepth" } }, - { "DPT", { 1000, 100, 0.0, 650.0, "formatDepth" } }, - { "HDM", { 1000, 10000, 0.0, M_TWOPI, "formatCourse" } }, - { "HDT", { 1000, 10000, 0.0, M_TWOPI, "formatCourse" } }, - { "ROT", { 1000, 10000, -M_PI / 180.0 * 99.0, M_PI / 180.0 * 99.0, "formatRot" } }, // min/max is -/+ 99 degrees for "rate of turn" - { "SOG", { 1000, 1000, 0.0, 65.0, "formatKnots" } }, - { "STW", { 1000, 1000, 0.0, 65.0, "formatKnots" } }, - { "TWA", { 1000, 10000, 0.0, M_TWOPI, "formatWind" } }, - { "TWD", { 1000, 10000, 0.0, M_TWOPI, "formatCourse" } }, - { "TWS", { 1000, 1000, 0.0, 65.0, "formatKnots" } }, - { "WTemp", { 1000, 100, 233.0, 650.0, "kelvinToC" } } // [-50..376] °C + { "AWA", { 1000, 10000, 0.0, M_TWOPI } }, + { "AWD", { 1000, 10000, 0.0, M_TWOPI } }, + { "AWS", { 1000, 1000, 0.0, 65.0 } }, + { "COG", { 1000, 10000, 0.0, M_TWOPI } }, + { "DBK", { 1000, 100, 0.0, 650.0 } }, + { "DBS", { 1000, 100, 0.0, 650.0 } }, + { "DBT", { 1000, 100, 0.0, 650.0 } }, + { "DPT", { 1000, 100, 0.0, 650.0 } }, + { "HDM", { 1000, 10000, 0.0, M_TWOPI } }, + { "HDT", { 1000, 10000, 0.0, M_TWOPI } }, + { "ROT", { 1000, 10000, -M_PI / 180.0 * 99.0, M_PI / 180.0 * 99.0 } }, // min/max is -/+ 99 degrees for "rate of turn" + { "SOG", { 1000, 1000, 0.0, 65.0 } }, + { "STW", { 1000, 1000, 0.0, 65.0 } }, + { "TWA", { 1000, 10000, 0.0, M_TWOPI } }, + { "TWD", { 1000, 10000, 0.0, M_TWOPI } }, + { "TWS", { 1000, 1000, 0.0, 65.0 } }, + { "WTemp", { 1000, 100, 263.0, 403.0 } }, // water temp [-10..130] °C + { "formatXdr:C:K", { 1000, 100, 223.0, 473.15 } }, // temperature [-50..200] deg celsius + { "formatXdr:P:B", { 1000, 1000, 0, 65.0 } }, // pressure [0..65] bar + { "formatXdr:P:P", { 60000, 0.1, 0, 650000 } }, // pressure [0..6500] hPa + { "formatXdr:H:P", { 1000, 100, 0, 100 } }, // humidity [0..100] percent + { "formatXdr:I:A", { 1000, 100, 0, 650.0 } }, // current [0..650] amperes + { "formatXdr:U:V", { 1000, 1000, 0, 65.0 } }, // voltage [0..65] volts + { "formatXdr:T:R", { 1000, 1, 0, 65000 } }, // tachometer [0..65000] rpm + { "formatXdr:V:L", { 10000, 100, 0, 650 } }, // volume [0..650] litres + { "formatXdr:V:M", { 10000, 10000, 0, 6.50 } }, // volume [0..6.5] m^3 + { "formatXdr:G:M", { 3000, 0.1, 0, 650000 } } // generic -> (pressure) [0..6500] hPa }; public: diff --git a/lib/obp60task/OBPRingBuffer.h b/lib/obp60task/OBPRingBuffer.h index b8047ab..c458e34 100644 --- a/lib/obp60task/OBPRingBuffer.h +++ b/lib/obp60task/OBPRingBuffer.h @@ -64,6 +64,7 @@ public: RingBuffer(); RingBuffer(size_t size); void setMetaData(String name, String format, int updateFrequency, double multiplier, double minValue, double maxValue); // Set meta data for buffer + void setFormat(String format); // Specify format of buffer bool getMetaData(String& name, String& format, int& updateFrequency, double& multiplier, double& minValue, double& maxValue); // Get meta data of buffer bool getMetaData(String& name, String& format); String getName() const; // Get buffer name diff --git a/lib/obp60task/OBPRingBuffer.tpp b/lib/obp60task/OBPRingBuffer.tpp index a1fdf06..dd256b1 100644 --- a/lib/obp60task/OBPRingBuffer.tpp +++ b/lib/obp60task/OBPRingBuffer.tpp @@ -60,6 +60,14 @@ void RingBuffer::setMetaData(String name, String format, int updateFrequency, largest = std::min(dblMAX_VAL, maxValue); } +// Specify format of buffer content +template +void RingBuffer::setFormat(String format) +{ + GWSYNCHRONIZED(&bufLocker); + dataFmt = format; +} + // Get meta data of buffer content template bool RingBuffer::getMetaData(String& name, String& format, int& updateFrequency, double& multiplier, double& minValue, double& maxValue)