Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare Release 2024.05.03 #948

Merged
merged 77 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
811b64a
PowerLimiter.cpp: simplification and minor correction of logic table …
DDvO Mar 25, 2024
eff8d52
better alignment inverter, issue 360
Mar 25, 2024
91a0992
fix: VE.Direct MPPT data not always updated in websocket
schlimmchen Mar 26, 2024
6f3b8fb
Fix: Change default NTP server
tbnobody Mar 31, 2024
1888054
Fix: Re-Request grid profile parameters if received data are invalid …
tbnobody Mar 31, 2024
f0a8cab
webapp: update dependencies
tbnobody Mar 31, 2024
bdff1e1
Added github workflow to do some repository cleanup
tbnobody Mar 31, 2024
1258865
webapp: add app.js.gz
tbnobody Mar 31, 2024
6940418
Move source files for TimeoutHelper to correct directories
tbnobody Mar 31, 2024
58efd9e
Move source files for ThreadSafeQueue to correct directories
tbnobody Mar 31, 2024
8add226
Save flash: Move WebApi json parsing to separate method to prevent a …
tbnobody Apr 1, 2024
7186900
Fix include for TimeoutHelper
tbnobody Apr 1, 2024
da96273
Fix typo in German locale (#831)
PhilJaro Apr 2, 2024
d2d775d
Update espressif32 from 6.5.0 to 6.6.0
tbnobody Apr 2, 2024
8abf614
Feature: BMS initiated emergency charging
MalteSchm Mar 18, 2024
187f197
Feature: add unique prefix to VE.Direct messages
schlimmchen Mar 29, 2024
ad125ea
Fix: properly handle fragmented VE.Direct messages
schlimmchen Mar 29, 2024
b299b9d
VE.Direct: simplify access to data
schlimmchen Mar 29, 2024
92a7f27
VE.Direct: use float rather than double
schlimmchen Mar 29, 2024
43f553d
VE.Direct MQTT: simplify code
schlimmchen Mar 29, 2024
8c6e925
VE.Direct: make state machine timeout robust against overflow
schlimmchen Mar 29, 2024
ff44267
Merge remote-tracking branch 'tbnobody/OpenDTU/master' into merge-v24…
helgeerbe Apr 3, 2024
aadd730
Feature: add support for VE.Direct hex messages
SW-Niko Mar 11, 2024
6b8c93d
polish VE.Direct HEX support
schlimmchen Mar 30, 2024
21cdc69
Feature: use VE.Direct "network total DC power"
schlimmchen Apr 1, 2024
b55ca53
Fix: Setting DTU options was only possible once without reboot
tbnobody Apr 3, 2024
aa10c2c
Fix: Too small event_queue_size in AsyncTCP lead to wdt reset
tbnobody Apr 3, 2024
3934906
Merge pull request #836 from helgeerbe/merge-v24.3.31
schlimmchen Apr 3, 2024
e7a9c96
Upgrade ESP Async WebServer from 2.8.1 to 2.9.0
tbnobody Apr 3, 2024
2e3125f
Feature: Migrated ArduinoJson 6 to 7
tbnobody Apr 2, 2024
980e847
Feature: Check for out of memory situations when sending json responses
tbnobody Apr 4, 2024
ea28903
Move parsing of serial from web request to separate method
tbnobody Apr 4, 2024
b9ad1e3
VE.Direct: process more values and refactor variable names
SW-Niko Apr 3, 2024
0ed09ae
Feature: Huawei: add SoC stop threshold and verbose logging switch
eu-gh Sep 18, 2023
165a9bc
adjust VE.Direct MPPT yield resulotion (#859)
PhilJaro Apr 9, 2024
a9c3e05
PowerMeter admin: URL examples to the top and hidden if disabled
schlimmchen Apr 10, 2024
f634f58
Fix: DPL: use correct channel type to get inverter efficiency
schlimmchen Apr 11, 2024
8b3a1be
Fix: show AC input power of Huawei AC charger in live view
schlimmchen Apr 11, 2024
153293e
remove remaining usage of F() macro
schlimmchen Apr 12, 2024
4c2822c
remove usage of F() macro
schlimmchen Apr 12, 2024
bf49410
Merge branch 'pr1909' into dev
tbnobody Apr 12, 2024
b58d086
webapp: update dependencies
tbnobody Apr 12, 2024
de156ef
webapp: Fix lint errors
tbnobody Apr 12, 2024
011f00e
Fix: If unauthenticaed, the redirect to login page did not work
tbnobody Apr 12, 2024
68b1a9e
Remove no more required web server patch
tbnobody Apr 12, 2024
d098193
webapp: add app.js.gz
tbnobody Apr 12, 2024
cf1ea42
power limiter: remove obsolete enum
schlimmchen Apr 9, 2024
7e30711
Feature: DPL: introduce base load setting
schlimmchen Apr 9, 2024
52d7ac9
Feature: DPL: support setups without power meter
schlimmchen Apr 10, 2024
5fcf09d
fix hysteresis hint texts
schlimmchen Apr 10, 2024
4bc4def
DPL: insist on power meter value more recent than inverter stats
schlimmchen Apr 11, 2024
e92701c
reuse power meter's HTTP config struct
schlimmchen Apr 16, 2024
247cfe7
HTTP power meter: prevent out-of-bound array access
schlimmchen Apr 16, 2024
ede1abb
Feature: HTTP power meter: support mW/kW as units
schlimmchen Apr 16, 2024
abe01ae
Feature: HTTP power meter: support changing sign
schlimmchen Apr 17, 2024
4cd690d
VE.Direct: publish data retrieved from HEX protocol
schlimmchen Apr 18, 2024
1d4bea2
Fix: JK BMS: BMS name is second part of product ID
schlimmchen Apr 18, 2024
eb9bfd1
Fix: DPL mode 2 for solar-powered inverters
schlimmchen Apr 21, 2024
c36369a
Upgrade ESP Async WebServer from 2.9.0 to 2.9.3
tbnobody Apr 23, 2024
21cadab
Upgrade olikraus/U8g2 from 2.35.15 to 2.35.17
tbnobody Apr 23, 2024
74330a5
Feature: restart unresponsive inverter
schlimmchen Apr 18, 2024
f0df583
Feature: support for Huawei target power consumption
MalteSchm Apr 24, 2024
f8cc171
Fix: Return 404 (and nothing else) if file not found
tbnobody Apr 24, 2024
2940301
Fix: Device Manager shows 404 if no pin_mapping.json was available
tbnobody Apr 24, 2024
5ab4b6d
webapp: update dependencies
tbnobody Apr 24, 2024
5a93a7e
Updated timezone config
tbnobody Apr 24, 2024
4623839
webapp: add app.js.gz
tbnobody Apr 24, 2024
fdc5054
Merge remote-tracking branch 'tbnobody/OpenDTU/master' into merge-v24…
helgeerbe Apr 25, 2024
64738a6
Introducing defines for RX2/TX2
MalteSchm Apr 25, 2024
84e83f2
adopt WebApiClass::parseRequestData() method
schlimmchen Apr 29, 2024
d3b306e
appease eslint
schlimmchen Apr 29, 2024
4e36c8c
Feature: battery interface: use HW serial 0 on ESP32-C3 or S3 (#933)
schlimmchen Apr 29, 2024
4cf596e
Merge pull request #923 from helgeerbe/merge-v24.4.12
schlimmchen Apr 29, 2024
18dab3c
Merge upstream tag 'v24.4.24' into development
schlimmchen May 2, 2024
744df41
Merge pull request #945 from helgeerbe/merge-v24.4.24
schlimmchen May 2, 2024
686b5df
Feature: Publish Huawei AC charger mode via MQTT (#876)
eu-gh May 2, 2024
6620ab4
Fix: VE.Direct: take the load current into account
SW-Niko Apr 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading