OpenDTU-old/src/JkBmsDataPoints.cpp
Bernhard Kirchen 24018a1432
JK BMS: Support for MQTT (#432)
* JK BMS: avoid trailing whitespace in debug output

* JK BMS: publish data points through MQTT

* JK BMS: updateFrom: skip data points with equal value

this changes the interpretation of the timestamp in data containers that
are merely updated from other data containers: this is the oldest
timestamp known where the value was as recorded by the data point in its
respective container.

the data container constructed from an answer will -- naturally -- have
the timetamps of its data points set to the time they were constructed.

* JK BMS: only publish changed values to MQTT broker

all values are still published once every minute if the MQTT retain flag
is NOT set. otherwise, the constant values are only published once on
startup.
2023-09-13 12:14:29 +02:00

64 lines
1.7 KiB
C++

#include <stdio.h>
#include "JkBmsDataPoints.h"
namespace JkBms {
static char conversionBuffer[16];
template<typename T>
std::string dataPointValueToStr(T const& v) {
snprintf(conversionBuffer, sizeof(conversionBuffer), "%d", v);
return conversionBuffer;
}
// explicit instanciations for the above unspecialized implementation
template std::string dataPointValueToStr(int16_t const& v);
template std::string dataPointValueToStr(int32_t const& v);
template std::string dataPointValueToStr(uint8_t const& v);
template std::string dataPointValueToStr(uint16_t const& v);
template std::string dataPointValueToStr(uint32_t const& v);
template<>
std::string dataPointValueToStr(std::string const& v) {
return v;
}
template<>
std::string dataPointValueToStr(bool const& v) {
return v?"yes":"no";
}
template<>
std::string dataPointValueToStr(tCells const& v) {
std::string res;
res.reserve(v.size()*(2+2+1+4)); // separator, index, equal sign, value
res += "(";
std::string sep = "";
for(auto const& mapval : v) {
snprintf(conversionBuffer, sizeof(conversionBuffer), "%s%d=%d",
sep.c_str(), mapval.first, mapval.second);
res += conversionBuffer;
sep = ", ";
}
res += ")";
return std::move(res);
}
void DataPointContainer::updateFrom(DataPointContainer const& source)
{
for (auto iter = source.cbegin(); iter != source.cend(); ++iter) {
auto pos = _dataPoints.find(iter->first);
if (pos != _dataPoints.end()) {
// do not update existing data points with the same value
if (pos->second == iter->second) { continue; }
_dataPoints.erase(pos);
}
_dataPoints.insert(*iter);
}
}
} /* namespace JkBms */