Skip to content

Commit

Permalink
Prepare Release 2024.05.03 (merge development into master)
Browse files Browse the repository at this point in the history
  • Loading branch information
schlimmchen committed May 3, 2024
2 parents dae50ec + 6620ab4 commit d2990bd
Show file tree
Hide file tree
Showing 127 changed files with 3,193 additions and 2,901 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/repo-maintenance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: 'Repository Maintenance'

on:
schedule:
- cron: '0 4 * * *'
workflow_dispatch:

permissions:
issues: write
pull-requests: write
discussions: write

concurrency:
group: lock

jobs:
stale:
name: 'Stale'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
days-before-stale: 14
days-before-close: 60
any-of-labels: 'cant-reproduce,not a bug'
stale-issue-label: stale
stale-pr-label: stale
stale-issue-message: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
lock-threads:
name: 'Lock Old Threads'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
with:
issue-inactive-days: '30'
pr-inactive-days: '30'
discussion-inactive-days: '30'
log-output: true
issue-comment: >
This issue has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new discussion or issue for related concerns.
pr-comment: >
This pull request has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new discussion or issue for related concerns.
discussion-comment: >
This discussion has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new discussion for related concerns.
12 changes: 9 additions & 3 deletions include/BatteryStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "Arduino.h"
#include "JkBmsDataPoints.h"
#include "VeDirectShuntController.h"
#include <cfloat>

// mandatory interface for all kinds of batteries
class BatteryStats {
Expand Down Expand Up @@ -37,7 +38,10 @@ class BatteryStats {

// returns true if the battery reached a critically low voltage/SoC,
// such that it is in need of charging to prevent degredation.
virtual bool needsCharging() const { return false; }
virtual bool getImmediateChargingRequest() const { return false; };

virtual float getChargeCurrent() const { return 0; };
virtual float getChargeCurrentLimitation() const { return FLT_MAX; };

protected:
virtual void mqttPublish() const;
Expand Down Expand Up @@ -71,7 +75,9 @@ class PylontechBatteryStats : public BatteryStats {
public:
void getLiveViewData(JsonVariant& root) const final;
void mqttPublish() const final;
bool needsCharging() const final { return _chargeImmediately; }
bool getImmediateChargingRequest() const { return _chargeImmediately; } ;
float getChargeCurrent() const { return _current; } ;
float getChargeCurrentLimitation() const { return _chargeCurrentLimitation; } ;

private:
void setManufacturer(String&& m) { _manufacturer = std::move(m); }
Expand Down Expand Up @@ -141,7 +147,7 @@ class VictronSmartShuntStats : public BatteryStats {
void getLiveViewData(JsonVariant& root) const final;
void mqttPublish() const final;

void updateFrom(VeDirectShuntController::veShuntStruct const& shuntData);
void updateFrom(VeDirectShuntController::data_t const& shuntData);

private:
float _current;
Expand Down
18 changes: 13 additions & 5 deletions include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <cstdint>

#define CONFIG_FILENAME "/config.json"
#define CONFIG_VERSION 0x00011b00 // 0.1.27 // make sure to clean all after change
#define CONFIG_VERSION 0x00011c00 // 0.1.28 // make sure to clean all after change

#define WIFI_MAX_SSID_STRLEN 32
#define WIFI_MAX_PASSWORD_STRLEN 64
Expand Down Expand Up @@ -39,8 +39,6 @@
#define POWERMETER_MAX_HTTP_JSON_PATH_STRLEN 256
#define POWERMETER_HTTP_TIMEOUT 1000

#define JSON_BUFFER_SIZE 15360

struct CHANNEL_CONFIG_T {
uint16_t MaxChannelPower;
char Name[CHAN_MAX_NAME_STRLEN];
Expand All @@ -62,8 +60,9 @@ struct INVERTER_CONFIG_T {
CHANNEL_CONFIG_T channel[INV_MAX_CHAN_COUNT];
};

enum Auth { none, basic, digest };
struct POWERMETER_HTTP_PHASE_CONFIG_T {
enum Auth { None, Basic, Digest };
enum Unit { Watts = 0, MilliWatts = 1, KiloWatts = 2 };
bool Enabled;
char Url[POWERMETER_MAX_HTTP_URL_STRLEN + 1];
Auth AuthType;
Expand All @@ -73,7 +72,10 @@ struct POWERMETER_HTTP_PHASE_CONFIG_T {
char HeaderValue[POWERMETER_MAX_HTTP_HEADER_VALUE_STRLEN + 1];
uint16_t Timeout;
char JsonPath[POWERMETER_MAX_HTTP_JSON_PATH_STRLEN + 1];
Unit PowerUnit;
bool SignInverted;
};
using PowerMeterHttpConfig = struct POWERMETER_HTTP_PHASE_CONFIG_T;

struct CONFIG_T {
struct {
Expand Down Expand Up @@ -196,7 +198,7 @@ struct CONFIG_T {
uint32_t SdmAddress;
uint32_t HttpInterval;
bool HttpIndividualRequests;
POWERMETER_HTTP_PHASE_CONFIG_T Http_Phase[POWERMETER_MAX_PHASES];
PowerMeterHttpConfig Http_Phase[POWERMETER_MAX_PHASES];
} PowerMeter;

struct {
Expand All @@ -213,6 +215,7 @@ struct CONFIG_T {
int32_t TargetPowerConsumption;
int32_t TargetPowerConsumptionHysteresis;
int32_t LowerPowerLimit;
int32_t BaseLoadLimit;
int32_t UpperPowerLimit;
bool IgnoreSoc;
uint32_t BatterySocStartThreshold;
Expand All @@ -238,12 +241,17 @@ struct CONFIG_T {

struct {
bool Enabled;
bool VerboseLogging;
uint32_t CAN_Controller_Frequency;
bool Auto_Power_Enabled;
bool Auto_Power_BatterySoC_Limits_Enabled;
bool Emergency_Charge_Enabled;
float Auto_Power_Voltage_Limit;
float Auto_Power_Enable_Voltage_Limit;
float Auto_Power_Lower_Power_Limit;
float Auto_Power_Upper_Power_Limit;
uint8_t Auto_Power_Stop_BatterySoC_Threshold;
float Auto_Power_Target_Power_Consumption;
} Huawei;


Expand Down
19 changes: 10 additions & 9 deletions include/HttpPowerMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,31 @@
#include <stdint.h>
#include <Arduino.h>
#include <HTTPClient.h>
#include "Configuration.h"

using Auth_t = PowerMeterHttpConfig::Auth;
using Unit_t = PowerMeterHttpConfig::Unit;

class HttpPowerMeterClass {
public:
void init();
bool updateValues();
float getPower(int8_t phase);
char httpPowerMeterError[256];
bool queryPhase(int phase, const String& url, Auth authType, const char* username, const char* password,
const char* httpHeader, const char* httpValue, uint32_t timeout, const char* jsonPath);

bool queryPhase(int phase, PowerMeterHttpConfig const& config);

private:
private:
float power[POWERMETER_MAX_PHASES];
HTTPClient httpClient;
String httpResponse;
bool httpRequest(int phase, WiFiClient &wifiClient, const String& host, uint16_t port, const String& uri, bool https, Auth authType, const char* username,
const char* password, const char* httpHeader, const char* httpValue, uint32_t timeout, const char* jsonPath);
bool httpRequest(int phase, WiFiClient &wifiClient, const String& host, uint16_t port, const String& uri, bool https, PowerMeterHttpConfig const& config);
bool extractUrlComponents(String url, String& _protocol, String& _hostname, String& _uri, uint16_t& uint16_t, String& _base64Authorization);
String extractParam(String& authReq, const String& param, const char delimit);
String getcNonce(const int len);
String getDigestAuth(String& authReq, const String& username, const String& password, const String& method, const String& uri, unsigned int counter);
bool tryGetFloatValueForPhase(int phase, const char* jsonPath);
void prepareRequest(uint32_t timeout, const char* httpHeader, const char* httpValue);
String sha256(const String& data);
bool tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit, bool signInverted);
void prepareRequest(uint32_t timeout, const char* httpHeader, const char* httpValue);
String sha256(const String& data);
};

extern HttpPowerMeterClass HttpPowerMeter;
12 changes: 7 additions & 5 deletions include/Huawei_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ class HuaweiCanCommClass {
SPIClass *SPI;
MCP_CAN *_CAN;
uint8_t _huaweiIrq; // IRQ pin
uint32_t _nextRequestMillis = 0; // When to send next data request to PSU
uint32_t _nextRequestMillis = 0; // When to send next data request to PSU

std::mutex _mutex;

uint32_t _recValues[12];
uint16_t _txValues[5];
bool _hasNewTxValue[5];

uint8_t _errorCode;
bool _completeUpdateReceived;
};
Expand All @@ -125,8 +125,9 @@ class HuaweiCanClass {
void setMode(uint8_t mode);

RectifierParameters_t * get();
uint32_t getLastUpdate();
bool getAutoPowerStatus();
uint32_t getLastUpdate() const { return _lastUpdateReceivedMillis; };
bool getAutoPowerStatus() const { return _autoPowerEnabled; };
uint8_t getMode() const { return _mode; };

private:
void loop();
Expand All @@ -150,7 +151,8 @@ class HuaweiCanClass {

uint8_t _autoPowerEnabledCounter = 0;
bool _autoPowerEnabled = false;
bool _batteryEmergencyCharging = false;
};

extern HuaweiCanClass HuaweiCan;
extern HuaweiCanCommClass HuaweiCanComm;
extern HuaweiCanCommClass HuaweiCanComm;
4 changes: 3 additions & 1 deletion include/JkBmsController.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class Controller : public BatteryProvider {
void deinit() final;
void loop() final;
std::shared_ptr<BatteryStats> getStats() const final { return _stats; }
bool usesHwPort2() const final { return true; }
bool usesHwPort2() const final {
return ARDUINO_USB_CDC_ON_BOOT != 1;
}

private:
enum class Status : unsigned {
Expand Down
6 changes: 3 additions & 3 deletions include/MqttHandleHass.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ class MqttHandleHassClass {
void publishInverterNumber(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* commandTopic, const char* stateTopic, const char* unitOfMeasure, const int16_t min = 1, const int16_t max = 100);
void publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off);

static void createInverterInfo(DynamicJsonDocument& doc, std::shared_ptr<InverterAbstract> inv);
static void createDtuInfo(DynamicJsonDocument& doc);
static void createInverterInfo(JsonDocument& doc, std::shared_ptr<InverterAbstract> inv);
static void createDtuInfo(JsonDocument& doc);

static void createDeviceInfo(DynamicJsonDocument& doc, const String& name, const String& identifiers, const String& configuration_url, const String& manufacturer, const String& model, const String& sw_version, const String& via_device = "");
static void createDeviceInfo(JsonDocument& doc, const String& name, const String& identifiers, const String& configuration_url, const String& manufacturer, const String& model, const String& sw_version, const String& via_device = "");

static String getDtuUniqueId();
static String getDtuUrl();
Expand Down
6 changes: 3 additions & 3 deletions include/MqttHandleVedirect.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class MqttHandleVedirectClass {
void forceUpdate();
private:
void loop();
std::map<std::string, VeDirectMpptController::veMpptStruct> _kvFrames;
std::map<std::string, VeDirectMpptController::data_t> _kvFrames;

Task _loopTask;

Expand All @@ -33,8 +33,8 @@ class MqttHandleVedirectClass {

bool _PublishFull;

void publish_mppt_data(const VeDirectMpptController::spData_t &spMpptData,
VeDirectMpptController::veMpptStruct &frame) const;
void publish_mppt_data(const VeDirectMpptController::data_t &mpptData,
const VeDirectMpptController::data_t &frame) const;
};

extern MqttHandleVedirectClass MqttHandleVedirect;
6 changes: 3 additions & 3 deletions include/MqttHandleVedirectHass.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ class MqttHandleVedirectHassClass {
void publish(const String& subtopic, const String& payload);
void publishBinarySensor(const char *caption, const char *icon, const char *subTopic,
const char *payload_on, const char *payload_off,
const VeDirectMpptController::spData_t &spMpptData);
const VeDirectMpptController::data_t &mpptData);
void publishSensor(const char *caption, const char *icon, const char *subTopic,
const char *deviceClass, const char *stateClass,
const char *unitOfMeasurement,
const VeDirectMpptController::spData_t &spMpptData);
const VeDirectMpptController::data_t &mpptData);
void createDeviceInfo(JsonObject &object,
const VeDirectMpptController::spData_t &spMpptData);
const VeDirectMpptController::data_t &mpptData);

Task _loopTask;

Expand Down
12 changes: 3 additions & 9 deletions include/PowerLimiter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,13 @@
#define PL_UI_STATE_USE_SOLAR_ONLY 2
#define PL_UI_STATE_USE_SOLAR_AND_BATTERY 3

typedef enum {
EMPTY_WHEN_FULL= 0,
EMPTY_AT_NIGHT
} batDrainStrategy;


class PowerLimiterClass {
public:
enum class Status : unsigned {
Initializing,
DisabledByConfig,
DisabledByMqtt,
WaitingForValidTimestamp,
PowerMeterDisabled,
PowerMeterTimeout,
PowerMeterPending,
InverterInvalid,
InverterChanged,
Expand All @@ -45,11 +37,11 @@ class PowerLimiterClass {
NoVeDirect,
NoEnergy,
HuaweiPsu,
Settling,
Stable,
};

void init(Scheduler& scheduler);
uint8_t getInverterUpdateTimeouts() const { return _inverterUpdateTimeouts; }
uint8_t getPowerLimiterState();
int32_t getLastRequestedPowerLimit() { return _lastRequestedPowerLimit; }

Expand All @@ -70,6 +62,7 @@ class PowerLimiterClass {

int32_t _lastRequestedPowerLimit = 0;
bool _shutdownPending = false;
std::optional<uint32_t> _oInverterStatsMillis = std::nullopt;
std::optional<uint32_t> _oUpdateStartMillis = std::nullopt;
std::optional<int32_t> _oTargetPowerLimitWatts = std::nullopt;
std::optional<bool> _oTargetPowerState = std::nullopt;
Expand All @@ -85,6 +78,7 @@ class PowerLimiterClass {
uint32_t _nextCalculateCheck = 5000; // time in millis for next NTP check to calulate restart
bool _fullSolarPassThroughEnabled = false;
bool _verboseLogging = true;
uint8_t _inverterUpdateTimeouts = 0;

frozen::string const& getStatusText(Status status);
void announceStatus(Status status);
Expand Down
1 change: 1 addition & 0 deletions include/PowerMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class PowerMeterClass {
void init(Scheduler& scheduler);
float getPowerTotal(bool forceUpdate = true);
uint32_t getLastPowerMeterUpdate();
bool isDataValid();

private:
void loop();
Expand Down
3 changes: 1 addition & 2 deletions include/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ class Utils {
static uint64_t generateDtuSerial();
static int getTimezoneOffset();
static void restartDtu();
static bool checkJsonAlloc(const DynamicJsonDocument& doc, const char* function, const uint16_t line);
static bool checkJsonOverflow(const DynamicJsonDocument& doc, const char* function, const uint16_t line);
static bool checkJsonAlloc(const JsonDocument& doc, const char* function, const uint16_t line);
static void removeAllFiles();
};
Loading

0 comments on commit d2990bd

Please sign in to comment.