forked from tbnobody/OpenDTU
-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for Jikong JK BMS using serial connection (#319)
- Loading branch information
1 parent
2ba7ea2
commit f744629
Showing
37 changed files
with
2,134 additions
and
788 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
|
||
#include "AsyncJson.h" | ||
#include "Arduino.h" | ||
#include "JkBmsDataPoints.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: | ||
template<typename T> | ||
void addLiveViewValue(JsonVariant& root, std::string const& name, | ||
T&& value, std::string const& unit, uint8_t precision) const; | ||
void addLiveViewText(JsonVariant& root, std::string const& name, | ||
std::string const& text) const; | ||
void addLiveViewWarning(JsonVariant& root, std::string const& name, | ||
bool warning) const; | ||
void addLiveViewAlarm(JsonVariant& root, std::string const& name, | ||
bool alarm) const; | ||
|
||
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; | ||
void mqttPublish() const final; | ||
|
||
void updateFrom(JkBms::DataPointContainer const& dp); | ||
|
||
private: | ||
JkBms::DataPointContainer _dataPoints; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
#include <vector> | ||
|
||
#include "Battery.h" | ||
#include "JkBmsSerialMessage.h" | ||
|
||
class DataPointContainer; | ||
|
||
namespace JkBms { | ||
|
||
class Controller : public BatteryProvider { | ||
public: | ||
Controller() = default; | ||
|
||
bool init(bool verboseLogging) final; | ||
void deinit() final; | ||
void loop() final; | ||
std::shared_ptr<BatteryStats> getStats() const final { return _stats; } | ||
|
||
private: | ||
enum class Status : unsigned { | ||
Initializing, | ||
Timeout, | ||
WaitingForPollInterval, | ||
HwSerialNotAvailableForWrite, | ||
BusyReading, | ||
RequestSent, | ||
FrameCompleted | ||
}; | ||
|
||
std::string const& getStatusText(Status status); | ||
void announceStatus(Status status); | ||
void sendRequest(uint8_t pollInterval); | ||
void rxData(uint8_t inbyte); | ||
void reset(); | ||
void frameComplete(); | ||
void processDataPoints(DataPointContainer const& dataPoints); | ||
|
||
enum class Interface : unsigned { | ||
Invalid, | ||
Uart, | ||
Transceiver | ||
}; | ||
|
||
Interface getInterface() const; | ||
|
||
enum class ReadState : unsigned { | ||
Idle, | ||
WaitingForFrameStart, | ||
FrameStartReceived, | ||
StartMarkerReceived, | ||
FrameLengthMsbReceived, | ||
ReadingFrame | ||
}; | ||
ReadState _readState; | ||
void setReadState(ReadState state) { | ||
_readState = state; | ||
} | ||
|
||
bool _verboseLogging = true; | ||
int8_t _rxEnablePin = -1; | ||
int8_t _txEnablePin = -1; | ||
Status _lastStatus = Status::Initializing; | ||
uint32_t _lastStatusPrinted = 0; | ||
uint32_t _lastRequest = 0; | ||
uint16_t _frameLength = 0; | ||
uint8_t _protocolVersion = -1; | ||
SerialResponse::tData _buffer = {}; | ||
std::shared_ptr<JkBmsBatteryStats> _stats = | ||
std::make_shared<JkBmsBatteryStats>(); | ||
}; | ||
|
||
} /* namespace JkBms */ |
Oops, something went wrong.