Skip to content

Commit

Permalink
JK BMS: publish cell voltages to MQTT broker
Browse files Browse the repository at this point in the history
  • Loading branch information
schlimmchen committed Dec 14, 2023
1 parent 06998d8 commit af87c57
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 19 deletions.
5 changes: 5 additions & 0 deletions include/BatteryStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ class JkBmsBatteryStats : public BatteryStats {
JkBms::DataPointContainer _dataPoints;
mutable uint32_t _lastMqttPublish = 0;
mutable uint32_t _lastFullMqttPublish = 0;

uint16_t _cellMinMilliVolt = 0;
uint16_t _cellAvgMilliVolt = 0;
uint16_t _cellMaxMilliVolt = 0;
uint32_t _cellVoltageTimestamp = 0;
};

class VictronSmartShuntStats : public BatteryStats {
Expand Down
59 changes: 40 additions & 19 deletions src/BatteryStats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,28 +127,16 @@ void JkBmsBatteryStats::getJsonData(JsonVariant& root, bool verbose) const
addLiveViewValue(root, "bmsTemp", *oTemperatureBms, "°C", 0);
}

auto oCellVoltages = _dataPoints.get<Label::CellsMilliVolt>();
if (oCellVoltages.has_value()) {
uint16_t minVolt = 0;
uint16_t avgVolt = 0;
uint16_t maxVolt = 0;
for (auto iter = oCellVoltages->cbegin(); iter != oCellVoltages->cend(); ++iter) {
if (iter == oCellVoltages->cbegin()) {
avgVolt = minVolt = maxVolt = iter->second;
continue;
}
minVolt = std::min(minVolt, iter->second);
avgVolt = (avgVolt + iter->second) / 2;
maxVolt = std::max(maxVolt, iter->second);
}

if (_cellVoltageTimestamp > 0) {
if (verbose) {
addLiveViewValue(root, "cellMinVoltage", static_cast<float>(minVolt)/1000, "V", 3);
addLiveViewValue(root, "cellMinVoltage", static_cast<float>(_cellMinMilliVolt)/1000, "V", 3);
}
addLiveViewValue(root, "cellAvgVoltage", static_cast<float>(avgVolt)/1000, "V", 3);

addLiveViewValue(root, "cellAvgVoltage", static_cast<float>(_cellAvgMilliVolt)/1000, "V", 3);

if (verbose) {
addLiveViewValue(root, "cellMaxVoltage", static_cast<float>(maxVolt)/1000, "V", 3);
addLiveViewValue(root, "cellDiffVoltage", (maxVolt - minVolt), "mV", 0);
addLiveViewValue(root, "cellMaxVoltage", static_cast<float>(_cellMaxMilliVolt)/1000, "V", 3);
addLiveViewValue(root, "cellDiffVoltage", (_cellMaxMilliVolt - _cellMinMilliVolt), "mV", 0);
}
}

Expand Down Expand Up @@ -257,6 +245,25 @@ void JkBmsBatteryStats::mqttPublish() const
MqttSettings.publish(topic, iter->second.getValueText().c_str());
}

auto oCellVoltages = _dataPoints.get<Label::CellsMilliVolt>();
if (oCellVoltages.has_value() && (fullPublish || _cellVoltageTimestamp > _lastMqttPublish)) {
unsigned idx = 1;
for (auto iter = oCellVoltages->cbegin(); iter != oCellVoltages->cend(); ++iter) {
String topic("battery/Cell");
topic += String(idx);
topic += "MilliVolt";

MqttSettings.publish(topic, String(iter->second));

++idx;
}

MqttSettings.publish("battery/CellMinMilliVolt", String(_cellMinMilliVolt));
MqttSettings.publish("battery/CellAvgMilliVolt", String(_cellAvgMilliVolt));
MqttSettings.publish("battery/CellMaxMilliVolt", String(_cellMaxMilliVolt));
MqttSettings.publish("battery/CellDiffMilliVolt", String(_cellMaxMilliVolt - _cellMinMilliVolt));
}

_lastMqttPublish = millis();
if (fullPublish) { _lastFullMqttPublish = _lastMqttPublish; }
}
Expand Down Expand Up @@ -284,6 +291,20 @@ void JkBmsBatteryStats::updateFrom(JkBms::DataPointContainer const& dp)

_dataPoints.updateFrom(dp);

auto oCellVoltages = _dataPoints.get<Label::CellsMilliVolt>();
if (oCellVoltages.has_value()) {
for (auto iter = oCellVoltages->cbegin(); iter != oCellVoltages->cend(); ++iter) {
if (iter == oCellVoltages->cbegin()) {
_cellMinMilliVolt = _cellAvgMilliVolt = _cellMaxMilliVolt = iter->second;
continue;
}
_cellMinMilliVolt = std::min(_cellMinMilliVolt, iter->second);
_cellAvgMilliVolt = (_cellAvgMilliVolt + iter->second) / 2;
_cellMaxMilliVolt = std::max(_cellMaxMilliVolt, iter->second);
}
_cellVoltageTimestamp = millis();
}

_lastUpdate = millis();
}

Expand Down

0 comments on commit af87c57

Please sign in to comment.