Feature: JK BMS: export (more) data to live view and MQTT (#549)
* add more values to web app live view. this should add all interesting values for the web app live view. those include important values and values that change frequently. * add more interesting JK BMS dummy messages: one has 0% SoC and an alarm (discharge undervoltage) set. the other has the undertemperature alarm set. * add alarms and warnings to live view * publish alarm and status bits through MQTT individually * publish cell voltages to MQTT broker * remove trailing spaces in BatteryStats class
This commit is contained in:
parent
dd8446df0a
commit
6e78c5bd1c
@ -89,15 +89,29 @@ class PylontechBatteryStats : public BatteryStats {
|
||||
|
||||
class JkBmsBatteryStats : public BatteryStats {
|
||||
public:
|
||||
void getLiveViewData(JsonVariant& root) const final;
|
||||
void getLiveViewData(JsonVariant& root) const final {
|
||||
getJsonData(root, false);
|
||||
}
|
||||
|
||||
void getInfoViewData(JsonVariant& root) const {
|
||||
getJsonData(root, true);
|
||||
}
|
||||
|
||||
void mqttPublish() const final;
|
||||
|
||||
void updateFrom(JkBms::DataPointContainer const& dp);
|
||||
|
||||
private:
|
||||
void getJsonData(JsonVariant& root, bool verbose) const;
|
||||
|
||||
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 {
|
||||
@ -107,8 +121,8 @@ class VictronSmartShuntStats : public BatteryStats {
|
||||
|
||||
void updateFrom(VeDirectShuntController::veShuntStruct const& shuntData);
|
||||
|
||||
private:
|
||||
float _voltage;
|
||||
private:
|
||||
float _voltage;
|
||||
float _current;
|
||||
float _temperature;
|
||||
bool _tempPresent;
|
||||
|
||||
@ -9,6 +9,54 @@
|
||||
|
||||
namespace JkBms {
|
||||
|
||||
#define ALARM_BITS(fnc) \
|
||||
fnc(LowCapacity, (1<<0)) \
|
||||
fnc(BmsOvertemperature, (1<<1)) \
|
||||
fnc(ChargingOvervoltage, (1<<2)) \
|
||||
fnc(DischargeUndervoltage, (1<<3)) \
|
||||
fnc(BatteryOvertemperature, (1<<4)) \
|
||||
fnc(ChargingOvercurrent, (1<<5)) \
|
||||
fnc(DischargeOvercurrent, (1<<6)) \
|
||||
fnc(CellVoltageDifference, (1<<7)) \
|
||||
fnc(BatteryBoxOvertemperature, (1<<8)) \
|
||||
fnc(BatteryUndertemperature, (1<<9)) \
|
||||
fnc(CellOvervoltage, (1<<10)) \
|
||||
fnc(CellUndervoltage, (1<<11)) \
|
||||
fnc(AProtect, (1<<12)) \
|
||||
fnc(BProtect, (1<<13)) \
|
||||
fnc(Reserved1, (1<<14)) \
|
||||
fnc(Reserved2, (1<<15))
|
||||
|
||||
enum class AlarmBits : uint16_t {
|
||||
#define ALARM_ENUM(name, value) name = value,
|
||||
ALARM_BITS(ALARM_ENUM)
|
||||
#undef ALARM_ENUM
|
||||
};
|
||||
|
||||
static const std::map<AlarmBits, std::string> AlarmBitTexts = {
|
||||
#define ALARM_TEXT(name, value) { AlarmBits::name, #name },
|
||||
ALARM_BITS(ALARM_TEXT)
|
||||
#undef ALARM_TEXT
|
||||
};
|
||||
|
||||
#define STATUS_BITS(fnc) \
|
||||
fnc(ChargingActive, (1<<0)) \
|
||||
fnc(DischargingActive, (1<<1)) \
|
||||
fnc(BalancingActive, (1<<2)) \
|
||||
fnc(BatteryOnline, (1<<3))
|
||||
|
||||
enum class StatusBits : uint16_t {
|
||||
#define STATUS_ENUM(name, value) name = value,
|
||||
STATUS_BITS(STATUS_ENUM)
|
||||
#undef STATUS_ENUM
|
||||
};
|
||||
|
||||
static const std::map<StatusBits, std::string> StatusBitTexts = {
|
||||
#define STATUS_TEXT(name, value) { StatusBits::name, #name },
|
||||
STATUS_BITS(STATUS_TEXT)
|
||||
#undef STATUS_TEXT
|
||||
};
|
||||
|
||||
enum class DataPointLabel : uint8_t {
|
||||
CellsMilliVolt = 0x79,
|
||||
BmsTempCelsius = 0x80,
|
||||
|
||||
@ -84,7 +84,7 @@ void PylontechBatteryStats::getLiveViewData(JsonVariant& root) const
|
||||
addLiveViewAlarm(root, "bmsInternal", _alarmBmsInternal);
|
||||
}
|
||||
|
||||
void JkBmsBatteryStats::getLiveViewData(JsonVariant& root) const
|
||||
void JkBmsBatteryStats::getJsonData(JsonVariant& root, bool verbose) const
|
||||
{
|
||||
BatteryStats::getLiveViewData(root);
|
||||
|
||||
@ -102,9 +102,80 @@ void JkBmsBatteryStats::getLiveViewData(JsonVariant& root) const
|
||||
static_cast<float>(*oCurrent) / 1000, "A", 2);
|
||||
}
|
||||
|
||||
auto oTemperature = _dataPoints.get<Label::BatteryTempOneCelsius>();
|
||||
if (oTemperature.has_value()) {
|
||||
addLiveViewValue(root, "temperature", *oTemperature, "°C", 0);
|
||||
if (oVoltage.has_value() && oCurrent.has_value()) {
|
||||
auto current = static_cast<float>(*oCurrent) / 1000;
|
||||
auto voltage = static_cast<float>(*oVoltage) / 1000;
|
||||
addLiveViewValue(root, "power", current * voltage , "W", 2);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
auto oTemperatureOne = _dataPoints.get<Label::BatteryTempOneCelsius>();
|
||||
if (oTemperatureOne.has_value()) {
|
||||
addLiveViewValue(root, "batOneTemp", *oTemperatureOne, "°C", 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
auto oTemperatureTwo = _dataPoints.get<Label::BatteryTempTwoCelsius>();
|
||||
if (oTemperatureTwo.has_value()) {
|
||||
addLiveViewValue(root, "batTwoTemp", *oTemperatureTwo, "°C", 0);
|
||||
}
|
||||
}
|
||||
|
||||
auto oTemperatureBms = _dataPoints.get<Label::BmsTempCelsius>();
|
||||
if (oTemperatureBms.has_value()) {
|
||||
addLiveViewValue(root, "bmsTemp", *oTemperatureBms, "°C", 0);
|
||||
}
|
||||
|
||||
if (_cellVoltageTimestamp > 0) {
|
||||
if (verbose) {
|
||||
addLiveViewValue(root, "cellMinVoltage", static_cast<float>(_cellMinMilliVolt)/1000, "V", 3);
|
||||
}
|
||||
|
||||
addLiveViewValue(root, "cellAvgVoltage", static_cast<float>(_cellAvgMilliVolt)/1000, "V", 3);
|
||||
|
||||
if (verbose) {
|
||||
addLiveViewValue(root, "cellMaxVoltage", static_cast<float>(_cellMaxMilliVolt)/1000, "V", 3);
|
||||
addLiveViewValue(root, "cellDiffVoltage", (_cellMaxMilliVolt - _cellMinMilliVolt), "mV", 0);
|
||||
}
|
||||
}
|
||||
|
||||
// labels BatteryChargeEnabled, BatteryDischargeEnabled, and
|
||||
// BalancingEnabled refer to the user setting. we want to show the
|
||||
// actual MOSFETs' state which control whether charging and discharging
|
||||
// is possible and whether the BMS is currently balancing cells.
|
||||
auto oStatus = _dataPoints.get<Label::StatusBitmask>();
|
||||
if (oStatus.has_value()) {
|
||||
using Bits = JkBms::StatusBits;
|
||||
auto chargeEnabled = *oStatus & static_cast<uint16_t>(Bits::ChargingActive);
|
||||
addLiveViewText(root, "chargeEnabled", (chargeEnabled?"yes":"no"));
|
||||
auto dischargeEnabled = *oStatus & static_cast<uint16_t>(Bits::DischargingActive);
|
||||
addLiveViewText(root, "dischargeEnabled", (dischargeEnabled?"yes":"no"));
|
||||
auto balancingActive = *oStatus & static_cast<uint16_t>(Bits::BalancingActive);
|
||||
addLiveViewText(root, "balancingActive", (balancingActive?"yes":"no"));
|
||||
}
|
||||
|
||||
auto oAlarms = _dataPoints.get<Label::AlarmsBitmask>();
|
||||
if (oAlarms.has_value()) {
|
||||
#define ISSUE(t, x) \
|
||||
auto x = *oAlarms & static_cast<uint16_t>(JkBms::AlarmBits::x); \
|
||||
addLiveView##t(root, "JkBmsIssue"#x, x > 0);
|
||||
|
||||
ISSUE(Warning, LowCapacity);
|
||||
ISSUE(Alarm, BmsOvertemperature);
|
||||
ISSUE(Alarm, ChargingOvervoltage);
|
||||
ISSUE(Alarm, DischargeUndervoltage);
|
||||
ISSUE(Alarm, BatteryOvertemperature);
|
||||
ISSUE(Alarm, ChargingOvercurrent);
|
||||
ISSUE(Alarm, DischargeOvercurrent);
|
||||
ISSUE(Alarm, CellVoltageDifference);
|
||||
ISSUE(Alarm, BatteryBoxOvertemperature);
|
||||
ISSUE(Alarm, BatteryUndertemperature);
|
||||
ISSUE(Alarm, CellOvervoltage);
|
||||
ISSUE(Alarm, CellUndervoltage);
|
||||
ISSUE(Alarm, AProtect);
|
||||
ISSUE(Alarm, BProtect);
|
||||
#undef ISSUE
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,6 +245,43 @@ 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));
|
||||
}
|
||||
|
||||
auto oAlarms = _dataPoints.get<Label::AlarmsBitmask>();
|
||||
if (oAlarms.has_value()) {
|
||||
for (auto iter = JkBms::AlarmBitTexts.begin(); iter != JkBms::AlarmBitTexts.end(); ++iter) {
|
||||
auto bit = iter->first;
|
||||
String value = (*oAlarms & static_cast<uint16_t>(bit))?"1":"0";
|
||||
MqttSettings.publish(String("battery/alarms/") + iter->second.c_str(), value);
|
||||
}
|
||||
}
|
||||
|
||||
auto oStatus = _dataPoints.get<Label::StatusBitmask>();
|
||||
if (oStatus.has_value()) {
|
||||
for (auto iter = JkBms::StatusBitTexts.begin(); iter != JkBms::StatusBitTexts.end(); ++iter) {
|
||||
auto bit = iter->first;
|
||||
String value = (*oStatus & static_cast<uint16_t>(bit))?"1":"0";
|
||||
MqttSettings.publish(String("battery/status/") + iter->second.c_str(), value);
|
||||
}
|
||||
}
|
||||
|
||||
_lastMqttPublish = millis();
|
||||
if (fullPublish) { _lastFullMqttPublish = _lastMqttPublish; }
|
||||
}
|
||||
@ -201,6 +309,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();
|
||||
}
|
||||
|
||||
@ -216,7 +338,7 @@ void VictronSmartShuntStats::updateFrom(VeDirectShuntController::veShuntStruct c
|
||||
_manufacturer = "Victron " + _modelName;
|
||||
_temperature = shuntData.T;
|
||||
_tempPresent = shuntData.tempPresent;
|
||||
|
||||
|
||||
// shuntData.AR is a bitfield, so we need to check each bit individually
|
||||
_alarmLowVoltage = shuntData.AR & 1;
|
||||
_alarmHighVoltage = shuntData.AR & 2;
|
||||
@ -233,19 +355,19 @@ void VictronSmartShuntStats::getLiveViewData(JsonVariant& root) const {
|
||||
|
||||
// values go into the "Status" card of the web application
|
||||
addLiveViewValue(root, "voltage", _voltage, "V", 2);
|
||||
addLiveViewValue(root, "current", _current, "A", 1);
|
||||
addLiveViewValue(root, "current", _current, "A", 1);
|
||||
addLiveViewValue(root, "chargeCycles", _chargeCycles, "", 0);
|
||||
addLiveViewValue(root, "chargedEnergy", _chargedEnergy, "KWh", 1);
|
||||
addLiveViewValue(root, "dischargedEnergy", _dischargedEnergy, "KWh", 1);
|
||||
if (_tempPresent) {
|
||||
addLiveViewValue(root, "temperature", _temperature, "°C", 0);
|
||||
}
|
||||
|
||||
|
||||
addLiveViewAlarm(root, "lowVoltage", _alarmLowVoltage);
|
||||
addLiveViewAlarm(root, "highVoltage", _alarmHighVoltage);
|
||||
addLiveViewAlarm(root, "lowSOC", _alarmLowSOC);
|
||||
addLiveViewAlarm(root, "lowTemperature", _alarmLowTemperature);
|
||||
addLiveViewAlarm(root, "highTemperature", _alarmHighTemperature);
|
||||
addLiveViewAlarm(root, "highTemperature", _alarmHighTemperature);
|
||||
}
|
||||
|
||||
void VictronSmartShuntStats::mqttPublish() const {
|
||||
|
||||
@ -113,6 +113,84 @@ class DummySerial {
|
||||
0x31, 0x41, 0x32, 0x34, 0x53, 0x31, 0x35, 0x50,
|
||||
0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x4f, 0xc1
|
||||
},
|
||||
{
|
||||
0x4e, 0x57, 0x01, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x01, 0x79, 0x30, 0x01, 0x0c, 0x13,
|
||||
0x02, 0x0c, 0x12, 0x03, 0x0c, 0x0f, 0x04, 0x0c,
|
||||
0x15, 0x05, 0x0c, 0x0d, 0x06, 0x0c, 0x13, 0x07,
|
||||
0x0c, 0x16, 0x08, 0x0c, 0x13, 0x09, 0x0b, 0xdb,
|
||||
0x0a, 0x0b, 0xf6, 0x0b, 0x0c, 0x17, 0x0c, 0x0b,
|
||||
0xf5, 0x0d, 0x0c, 0x16, 0x0e, 0x0c, 0x1a, 0x0f,
|
||||
0x0c, 0x1b, 0x10, 0x0c, 0x1c, 0x80, 0x00, 0x18,
|
||||
0x81, 0x00, 0x18, 0x82, 0x00, 0x18, 0x83, 0x13,
|
||||
0x49, 0x84, 0x00, 0x00, 0x85, 0x00, 0x86, 0x02,
|
||||
0x87, 0x00, 0x23, 0x89, 0x00, 0x00, 0x20, 0x14,
|
||||
0x8a, 0x00, 0x10, 0x8b, 0x00, 0x08, 0x8c, 0x00,
|
||||
0x05, 0x8e, 0x16, 0x80, 0x8f, 0x12, 0xc0, 0x90,
|
||||
0x0e, 0x10, 0x91, 0x0c, 0xda, 0x92, 0x00, 0x05,
|
||||
0x93, 0x0b, 0xb8, 0x94, 0x0c, 0x80, 0x95, 0x00,
|
||||
0x05, 0x96, 0x01, 0x2c, 0x97, 0x00, 0x28, 0x98,
|
||||
0x01, 0x2c, 0x99, 0x00, 0x28, 0x9a, 0x00, 0x1e,
|
||||
0x9b, 0x0b, 0xb8, 0x9c, 0x00, 0x0a, 0x9d, 0x01,
|
||||
0x9e, 0x00, 0x64, 0x9f, 0x00, 0x50, 0xa0, 0x00,
|
||||
0x64, 0xa1, 0x00, 0x64, 0xa2, 0x00, 0x14, 0xa3,
|
||||
0x00, 0x46, 0xa4, 0x00, 0x46, 0xa5, 0x00, 0x00,
|
||||
0xa6, 0x00, 0x02, 0xa7, 0xff, 0xec, 0xa8, 0xff,
|
||||
0xf6, 0xa9, 0x10, 0xaa, 0x00, 0x00, 0x00, 0xe6,
|
||||
0xab, 0x01, 0xac, 0x01, 0xad, 0x04, 0x4d, 0xae,
|
||||
0x01, 0xaf, 0x00, 0xb0, 0x00, 0x0a, 0xb1, 0x14,
|
||||
0xb2, 0x32, 0x32, 0x31, 0x31, 0x38, 0x37, 0x00,
|
||||
0x00, 0x00, 0x00, 0xb3, 0x00, 0xb4, 0x62, 0x65,
|
||||
0x6b, 0x69, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x32,
|
||||
0x33, 0x30, 0x36, 0xb6, 0x00, 0x02, 0x17, 0x10,
|
||||
0xb7, 0x31, 0x31, 0x2e, 0x58, 0x57, 0x5f, 0x53,
|
||||
0x31, 0x31, 0x2e, 0x32, 0x36, 0x32, 0x48, 0x5f,
|
||||
0xb8, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xe6, 0xba,
|
||||
0x62, 0x65, 0x6b, 0x69, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x4a, 0x4b, 0x5f, 0x42,
|
||||
0x31, 0x41, 0x32, 0x34, 0x53, 0x31, 0x35, 0x50,
|
||||
0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x45, 0xce
|
||||
},
|
||||
{
|
||||
0x4e, 0x57, 0x01, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x01, 0x79, 0x30, 0x01, 0x0c, 0x07,
|
||||
0x02, 0x0c, 0x0a, 0x03, 0x0c, 0x0b, 0x04, 0x0c,
|
||||
0x08, 0x05, 0x0c, 0x05, 0x06, 0x0c, 0x0b, 0x07,
|
||||
0x0c, 0x07, 0x08, 0x0c, 0x0a, 0x09, 0x0c, 0x08,
|
||||
0x0a, 0x0c, 0x06, 0x0b, 0x0c, 0x0a, 0x0c, 0x0c,
|
||||
0x05, 0x0d, 0x0c, 0x0a, 0x0e, 0x0c, 0x0a, 0x0f,
|
||||
0x0c, 0x0a, 0x10, 0x0c, 0x0a, 0x80, 0x00, 0x06,
|
||||
0x81, 0x00, 0x03, 0x82, 0x00, 0x03, 0x83, 0x13,
|
||||
0x40, 0x84, 0x00, 0x00, 0x85, 0x29, 0x86, 0x02,
|
||||
0x87, 0x00, 0x01, 0x89, 0x00, 0x00, 0x01, 0x0a,
|
||||
0x8a, 0x00, 0x10, 0x8b, 0x02, 0x00, 0x8c, 0x00,
|
||||
0x02, 0x8e, 0x16, 0x80, 0x8f, 0x10, 0x40, 0x90,
|
||||
0x0e, 0x10, 0x91, 0x0d, 0xde, 0x92, 0x00, 0x05,
|
||||
0x93, 0x0a, 0x28, 0x94, 0x0a, 0x5a, 0x95, 0x00,
|
||||
0x05, 0x96, 0x01, 0x2c, 0x97, 0x00, 0x28, 0x98,
|
||||
0x01, 0x2c, 0x99, 0x00, 0x28, 0x9a, 0x00, 0x1e,
|
||||
0x9b, 0x0b, 0xb8, 0x9c, 0x00, 0x0a, 0x9d, 0x01,
|
||||
0x9e, 0x00, 0x5a, 0x9f, 0x00, 0x50, 0xa0, 0x00,
|
||||
0x64, 0xa1, 0x00, 0x64, 0xa2, 0x00, 0x14, 0xa3,
|
||||
0x00, 0x37, 0xa4, 0x00, 0x37, 0xa5, 0x00, 0x03,
|
||||
0xa6, 0x00, 0x05, 0xa7, 0xff, 0xec, 0xa8, 0xff,
|
||||
0xf6, 0xa9, 0x10, 0xaa, 0x00, 0x00, 0x00, 0xe6,
|
||||
0xab, 0x01, 0xac, 0x01, 0xad, 0x04, 0x4d, 0xae,
|
||||
0x01, 0xaf, 0x00, 0xb0, 0x00, 0x0a, 0xb1, 0x14,
|
||||
0xb2, 0x32, 0x32, 0x31, 0x31, 0x38, 0x37, 0x00,
|
||||
0x00, 0x00, 0x00, 0xb3, 0x00, 0xb4, 0x62, 0x65,
|
||||
0x6b, 0x69, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x32,
|
||||
0x33, 0x30, 0x36, 0xb6, 0x00, 0x03, 0xb7, 0x2d,
|
||||
0xb7, 0x31, 0x31, 0x2e, 0x58, 0x57, 0x5f, 0x53,
|
||||
0x31, 0x31, 0x2e, 0x32, 0x36, 0x32, 0x48, 0x5f,
|
||||
0xb8, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xe6, 0xba,
|
||||
0x62, 0x65, 0x6b, 0x69, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x4a, 0x4b, 0x5f, 0x42,
|
||||
0x31, 0x41, 0x32, 0x34, 0x53, 0x31, 0x35, 0x50,
|
||||
0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x41, 0x7b
|
||||
}
|
||||
};
|
||||
size_t _msg_idx = 0;
|
||||
|
||||
@ -804,19 +804,37 @@
|
||||
"stateOfHealth": "Batteriezustand (SoH)",
|
||||
"voltage": "Spannung",
|
||||
"current": "Strom",
|
||||
"power": "Leistung",
|
||||
"temperature": "Temperatur",
|
||||
"bmsTemp": "BMS-Temperatur",
|
||||
"chargeVoltage": "Gewünschte Ladespannung (BMS)",
|
||||
"chargeCurrentLimitation": "Ladestromlimit",
|
||||
"dischargeCurrentLimitation": "Entladestromlimit",
|
||||
"chargeEnabled": "Laden ermöglicht",
|
||||
"dischargeEnabled": "Entladen ermöglicht",
|
||||
"balancingActive": "Ausgleichen aktiv",
|
||||
"chargeImmediately": "Sofortiges Laden angefordert",
|
||||
"cellAvgVoltage": "Durchschnittliche Zellspannung",
|
||||
"issues": "Meldungen",
|
||||
"noIssues": "Keine Meldungen",
|
||||
"issueName": "Bezeichnung",
|
||||
"issueType": "Art",
|
||||
"alarm": "Alarm",
|
||||
"warning": "Warnung",
|
||||
"JkBmsIssueLowCapacity": "Niedrige Kapazität",
|
||||
"JkBmsIssueBmsOvertemperature": "BMS Übertemperatur",
|
||||
"JkBmsIssueChargingOvervoltage": "Überspannung (Akkupack)",
|
||||
"JkBmsIssueDischargeUndervoltage": "Unterspannung (Akkupack)",
|
||||
"JkBmsIssueBatteryOvertemperature": "Batterie Übertemperatur",
|
||||
"JkBmsIssueChargingOvercurrent": "Überstrom (Laden)",
|
||||
"JkBmsIssueDischargeOvercurrent": "Überstrom (Entladen)",
|
||||
"JkBmsIssueCellVoltageDifference": "Zellspannungsdifferenz zu hoch",
|
||||
"JkBmsIssueBatteryBoxOvertemperature": "Batterie (Box?) Übertemperatur",
|
||||
"JkBmsIssueBatteryUndertemperature": "Batterie Untertemperatur",
|
||||
"JkBmsIssueCellOvervoltage": "Überspannung (einzelne Zelle)",
|
||||
"JkBmsIssueCellUndervoltage": "Unterspannung (einzelne Zelle)",
|
||||
"JkBmsIssueAProtect": "AProtect (Bedeutung?)",
|
||||
"JkBmsIssueBProtect": "BProtect (Bedeutung?)",
|
||||
"highCurrentDischarge": "Hoher Entladestrom",
|
||||
"overCurrentDischarge": "Überstrom (Entladen)",
|
||||
"highCurrentCharge": "Hoher Ladestrom",
|
||||
|
||||
@ -814,19 +814,37 @@
|
||||
"stateOfHealth": "State of Health",
|
||||
"voltage": "Voltage",
|
||||
"current": "Current",
|
||||
"power": "Power",
|
||||
"temperature": "Temperature",
|
||||
"bmsTemp": "BMS temperature",
|
||||
"chargeVoltage": "Requested charge voltage",
|
||||
"chargeCurrentLimitation": "Charge current limit",
|
||||
"dischargeCurrentLimitation": "Discharge current limit",
|
||||
"chargeEnabled": "Charging possible",
|
||||
"dischargeEnabled": "Discharging possible",
|
||||
"balancingActive": "Balancing active",
|
||||
"chargeImmediately": "Immediate charging requested",
|
||||
"cellAvgVoltage": "Average cell voltage",
|
||||
"issues": "Issues",
|
||||
"noIssues": "No Issues",
|
||||
"issueName": "Name",
|
||||
"issueType": "Type",
|
||||
"alarm": "Alarm",
|
||||
"warning": "Warning",
|
||||
"JkBmsIssueLowCapacity": "Low Capacity",
|
||||
"JkBmsIssueBmsOvertemperature": "BMS overtemperature",
|
||||
"JkBmsIssueChargingOvervoltage": "Overvoltage (sum of all cells)",
|
||||
"JkBmsIssueDischargeUndervoltage": "Undervoltage (sum of all cells)",
|
||||
"JkBmsIssueBatteryOvertemperature": "Battery overtemperature",
|
||||
"JkBmsIssueChargingOvercurrent": "Overcurrent (Charging)",
|
||||
"JkBmsIssueDischargeOvercurrent": "Overcurrent (Discharging)",
|
||||
"JkBmsIssueCellVoltageDifference": "Cell voltage difference too high",
|
||||
"JkBmsIssueBatteryBoxOvertemperature": "Battery (box?) overtemperature",
|
||||
"JkBmsIssueBatteryUndertemperature": "Battery undertemperature",
|
||||
"JkBmsIssueCellOvervoltage": "Overvoltage (single cell)",
|
||||
"JkBmsIssueCellUndervoltage": "Undervoltage (single cell)",
|
||||
"JkBmsIssueAProtect": "AProtect (meaning?)",
|
||||
"JkBmsIssueBProtect": "BProtect (meaning?)",
|
||||
"highCurrentDischarge": "High current (discharge)",
|
||||
"overCurrentDischarge": "Overcurrent (discharge)",
|
||||
"highCurrentCharge": "High current (charge)",
|
||||
|
||||
@ -757,7 +757,7 @@
|
||||
"Save": "@:dtuadmin.Save"
|
||||
},
|
||||
"battery": {
|
||||
"battery": "battery",
|
||||
"battery": "Battery",
|
||||
"DataAge": "Data Age: ",
|
||||
"Seconds": " {val} seconds",
|
||||
"Status": "Status",
|
||||
@ -766,20 +766,41 @@
|
||||
"no": "@:base.No",
|
||||
"Value": "Value",
|
||||
"Unit": "Unit",
|
||||
"SoC": "State of charge",
|
||||
"stateOfHealth": "State of health",
|
||||
"SoC": "State of Charge",
|
||||
"stateOfHealth": "State of Health",
|
||||
"voltage": "Voltage",
|
||||
"current": "Current",
|
||||
"power": "Power",
|
||||
"temperature": "Temperature",
|
||||
"bmsTemp": "BMS temperature",
|
||||
"chargeVoltage": "Requested charge voltage",
|
||||
"chargeCurrentLimitation": "Charge current limit",
|
||||
"dischargeCurrentLimitation": "Discharge current limit",
|
||||
"chargeEnabled": "Charging possible",
|
||||
"dischargeEnabled": "Discharging possible",
|
||||
"balancingActive": "Balancing active",
|
||||
"chargeImmediately": "Immediate charging requested",
|
||||
"cellAvgVoltage": "Average cell voltage",
|
||||
"issues": "Issues",
|
||||
"noIssues": "No Issues",
|
||||
"issueName": "Name",
|
||||
"issueType": "Type",
|
||||
"alarm": "Alarm",
|
||||
"warning": "Warning",
|
||||
"JkBmsIssueLowCapacity": "Low Capacity",
|
||||
"JkBmsIssueBmsOvertemperature": "BMS overtemperature",
|
||||
"JkBmsIssueChargingOvervoltage": "Overvoltage (sum of all cells)",
|
||||
"JkBmsIssueDischargeUndervoltage": "Undervoltage (sum of all cells)",
|
||||
"JkBmsIssueBatteryOvertemperature": "Battery overtemperature",
|
||||
"JkBmsIssueChargingOvercurrent": "Overcurrent (Charging)",
|
||||
"JkBmsIssueDischargeOvercurrent": "Overcurrent (Discharging)",
|
||||
"JkBmsIssueCellVoltageDifference": "Cell voltage difference too high",
|
||||
"JkBmsIssueBatteryBoxOvertemperature": "Battery (box?) overtemperature",
|
||||
"JkBmsIssueBatteryUndertemperature": "Battery undertemperature",
|
||||
"JkBmsIssueCellOvervoltage": "Overvoltage (single cell)",
|
||||
"JkBmsIssueCellUndervoltage": "Undervoltage (single cell)",
|
||||
"JkBmsIssueAProtect": "AProtect (meaning?)",
|
||||
"JkBmsIssueBProtect": "BProtect (meaning?)",
|
||||
"highCurrentDischarge": "High current (discharge)",
|
||||
"overCurrentDischarge": "Overcurrent (discharge)",
|
||||
"highCurrentCharge": "High current (charge)",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user