this battery provider implementation subscribes to a user-configurable MQTT topic to retrieve the battery SoC value. the value is not re-published under a different topic. there is no card created in the web app's live view, since the SoC is already part of the totals at the top of the live view. that is the only info this battery provider implements. closes #293. relates to #581.
144 lines
4.4 KiB
C++
144 lines
4.4 KiB
C++
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "AsyncJson.h"
|
|
#include "Arduino.h"
|
|
#include "JkBmsDataPoints.h"
|
|
#include "VeDirectShuntController.h"
|
|
|
|
// mandatory interface for all kinds of batteries
|
|
class BatteryStats {
|
|
public:
|
|
String const& getManufacturer() const { return _manufacturer; }
|
|
|
|
// the last time *any* datum was updated
|
|
uint32_t getAgeSeconds() const { return (millis() - _lastUpdate) / 1000; }
|
|
bool updateAvailable(uint32_t since) const { return _lastUpdate > since; }
|
|
|
|
uint8_t getSoC() const { return _SoC; }
|
|
uint32_t getSoCAgeSeconds() const { return (millis() - _lastUpdateSoC) / 1000; }
|
|
|
|
// convert stats to JSON for web application live view
|
|
virtual void getLiveViewData(JsonVariant& root) const;
|
|
|
|
virtual void mqttPublish() const;
|
|
|
|
bool isValid() const { return _lastUpdateSoC > 0 && _lastUpdate > 0; }
|
|
|
|
protected:
|
|
String _manufacturer = "unknown";
|
|
uint8_t _SoC = 0;
|
|
uint32_t _lastUpdateSoC = 0;
|
|
uint32_t _lastUpdate = 0;
|
|
};
|
|
|
|
class PylontechBatteryStats : public BatteryStats {
|
|
friend class PylontechCanReceiver;
|
|
|
|
public:
|
|
void getLiveViewData(JsonVariant& root) const final;
|
|
void mqttPublish() const final;
|
|
|
|
private:
|
|
void setManufacturer(String&& m) { _manufacturer = std::move(m); }
|
|
void setSoC(uint8_t SoC) { _SoC = SoC; _lastUpdateSoC = millis(); }
|
|
void setLastUpdate(uint32_t ts) { _lastUpdate = ts; }
|
|
|
|
float _chargeVoltage;
|
|
float _chargeCurrentLimitation;
|
|
float _dischargeCurrentLimitation;
|
|
uint16_t _stateOfHealth;
|
|
float _voltage; // total voltage of the battery pack
|
|
// total current into (positive) or from (negative)
|
|
// the battery, i.e., the charging current
|
|
float _current;
|
|
float _temperature;
|
|
|
|
bool _alarmOverCurrentDischarge;
|
|
bool _alarmOverCurrentCharge;
|
|
bool _alarmUnderTemperature;
|
|
bool _alarmOverTemperature;
|
|
bool _alarmUnderVoltage;
|
|
bool _alarmOverVoltage;
|
|
bool _alarmBmsInternal;
|
|
|
|
bool _warningHighCurrentDischarge;
|
|
bool _warningHighCurrentCharge;
|
|
bool _warningLowTemperature;
|
|
bool _warningHighTemperature;
|
|
bool _warningLowVoltage;
|
|
bool _warningHighVoltage;
|
|
bool _warningBmsInternal;
|
|
|
|
bool _chargeEnabled;
|
|
bool _dischargeEnabled;
|
|
bool _chargeImmediately;
|
|
};
|
|
|
|
class JkBmsBatteryStats : public BatteryStats {
|
|
public:
|
|
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 {
|
|
public:
|
|
void getLiveViewData(JsonVariant& root) const final;
|
|
void mqttPublish() const final;
|
|
|
|
void updateFrom(VeDirectShuntController::veShuntStruct const& shuntData);
|
|
|
|
private:
|
|
float _voltage;
|
|
float _current;
|
|
float _temperature;
|
|
bool _tempPresent;
|
|
uint8_t _chargeCycles;
|
|
uint32_t _timeToGo;
|
|
float _chargedEnergy;
|
|
float _dischargedEnergy;
|
|
String _modelName;
|
|
|
|
bool _alarmLowVoltage;
|
|
bool _alarmHighVoltage;
|
|
bool _alarmLowSOC;
|
|
bool _alarmLowTemperature;
|
|
bool _alarmHighTemperature;
|
|
};
|
|
|
|
class MqttBatteryStats : public BatteryStats {
|
|
public:
|
|
// since the source of information was MQTT in the first place,
|
|
// we do NOT publish the same data under a different topic.
|
|
void mqttPublish() const final { }
|
|
|
|
// the SoC is the only interesting value in this case, which is already
|
|
// displayed at the top of the live view. do not generate a card.
|
|
void getLiveViewData(JsonVariant& root) const final { }
|
|
|
|
void setSoC(uint8_t SoC) { _SoC = SoC; _lastUpdateSoC = _lastUpdate = millis(); }
|
|
};
|