Skip to content

Commit

Permalink
Prepare Release 2024.09.11
Browse files Browse the repository at this point in the history
  • Loading branch information
schlimmchen authored Sep 11, 2024
2 parents f8ad0a4 + 1fe8d3f commit 83ed72e
Show file tree
Hide file tree
Showing 48 changed files with 508 additions and 159 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
platformio-device-monitor*.log
logs/device-monitor*.log
platformio_override.ini
webapp_dist/
.DS_Store
8 changes: 4 additions & 4 deletions include/BatteryStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class BatteryStats {
uint32_t getAgeSeconds() const { return (millis() - _lastUpdate) / 1000; }
bool updateAvailable(uint32_t since) const;

uint8_t getSoC() const { return _soc; }
float getSoC() const { return _soc; }
uint32_t getSoCAgeSeconds() const { return (millis() - _lastUpdateSoC) / 1000; }
uint8_t getSoCPrecision() const { return _socPrecision; }

Expand Down Expand Up @@ -67,13 +67,15 @@ class BatteryStats {
_lastUpdateCurrent = _lastUpdate = timestamp;
}

String _manufacturer = "unknown";
void setManufacturer(const String& m);

String _hwversion = "";
String _fwversion = "";
String _serial = "";
uint32_t _lastUpdate = 0;

private:
String _manufacturer = "unknown";
uint32_t _lastMqttPublish = 0;
float _soc = 0;
uint8_t _socPrecision = 0; // decimal places
Expand All @@ -98,7 +100,6 @@ class PylontechBatteryStats : public BatteryStats {
float getChargeCurrentLimitation() const { return _chargeCurrentLimitation; } ;

private:
void setManufacturer(String&& m) { _manufacturer = std::move(m); }
void setLastUpdate(uint32_t ts) { _lastUpdate = ts; }

float _chargeVoltage;
Expand Down Expand Up @@ -137,7 +138,6 @@ class PytesBatteryStats : public BatteryStats {
float getChargeCurrentLimitation() const { return _chargeCurrentLimit; } ;

private:
void setManufacturer(String&& m) { _manufacturer = std::move(m); }
void setLastUpdate(uint32_t ts) { _lastUpdate = ts; }
void updateSerial() {
if (!_serialPart1.isEmpty() && !_serialPart2.isEmpty()) {
Expand Down
17 changes: 15 additions & 2 deletions include/HttpGetter.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,17 @@
#include <HTTPClient.h>
#include <WiFiClient.h>

using up_http_client_t = std::unique_ptr<HTTPClient>;
class HttpGetterClient : public HTTPClient {
public:
void restartTCP() {
// keeps the NetworkClient, and closes the TCP connections (as we
// effectively do not support keep-alive with HTTP 1.0).
HTTPClient::disconnect(true);
HTTPClient::connect();
}
};

using up_http_client_t = std::unique_ptr<HttpGetterClient>;
using sp_wifi_client_t = std::shared_ptr<WiFiClient>;

class HttpRequestResult {
Expand Down Expand Up @@ -59,7 +69,7 @@ class HttpGetter {
char const* getErrorText() const { return _errBuffer; }

private:
String getAuthDigest(String const& authReq, unsigned int counter);
std::pair<bool, String> getAuthDigest();
HttpRequestConfig const& _config;

template<typename... Args>
Expand All @@ -71,6 +81,9 @@ class HttpGetter {
String _uri;
uint16_t _port;

String _wwwAuthenticate = "";
unsigned _nonceCounter = 0;

sp_wifi_client_t _spWiFiClient; // reused for multiple HTTP requests

std::vector<std::pair<std::string, std::string>> _additionalHeaders;
Expand Down
16 changes: 16 additions & 0 deletions include/MqttHandleHuawei.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@
#include <mutex>
#include <deque>
#include <functional>
#include <frozen/map.h>
#include <frozen/string.h>

class MqttHandleHuaweiClass {
public:
void init(Scheduler& scheduler);

void forceUpdate();

void subscribeTopics();
void unsubscribeTopics();

private:
void loop();

Expand All @@ -24,6 +31,15 @@ class MqttHandleHuaweiClass {
Mode
};

static constexpr frozen::string _cmdtopic = "huawei/cmd/";
static constexpr frozen::map<frozen::string, Topic, 5> _subscriptions = {
{ "limit_online_voltage", Topic::LimitOnlineVoltage },
{ "limit_online_current", Topic::LimitOnlineCurrent },
{ "limit_offline_voltage", Topic::LimitOfflineVoltage },
{ "limit_offline_current", Topic::LimitOfflineCurrent },
{ "mode", Topic::Mode },
};

void onMqttMessage(Topic t,
const espMqttClientTypes::MessageProperties& properties,
const char* topic, const uint8_t* payload, size_t len,
Expand Down
21 changes: 21 additions & 0 deletions include/MqttHandlePowerLimiter.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@
#include <mutex>
#include <deque>
#include <functional>
#include <frozen/map.h>
#include <frozen/string.h>

class MqttHandlePowerLimiterClass {
public:
void init(Scheduler& scheduler);

void forceUpdate();

void subscribeTopics();
void unsubscribeTopics();

private:
void loop();

Expand All @@ -28,6 +35,20 @@ class MqttHandlePowerLimiterClass {
TargetPowerConsumption
};

static constexpr frozen::string _cmdtopic = "powerlimiter/cmd/";
static constexpr frozen::map<frozen::string, MqttPowerLimiterCommand, 10> _subscriptions = {
{ "threshold/soc/start", MqttPowerLimiterCommand::BatterySoCStartThreshold },
{ "threshold/soc/stop", MqttPowerLimiterCommand::BatterySoCStopThreshold },
{ "threshold/soc/full_solar_passthrough", MqttPowerLimiterCommand::FullSolarPassthroughSoC },
{ "threshold/voltage/start", MqttPowerLimiterCommand::VoltageStartThreshold },
{ "threshold/voltage/stop", MqttPowerLimiterCommand::VoltageStopThreshold },
{ "threshold/voltage/full_solar_passthrough_start", MqttPowerLimiterCommand::FullSolarPassThroughStartVoltage },
{ "threshold/voltage/full_solar_passthrough_stop", MqttPowerLimiterCommand::FullSolarPassThroughStopVoltage },
{ "mode", MqttPowerLimiterCommand::Mode },
{ "upper_power_limit", MqttPowerLimiterCommand::UpperPowerLimit },
{ "target_power_consumption", MqttPowerLimiterCommand::TargetPowerConsumption },
};

void onMqttCmd(MqttPowerLimiterCommand command, const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);

Task _loopTask;
Expand Down
2 changes: 1 addition & 1 deletion include/PowerMeterHttpJson.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class PowerMeterHttpJson : public PowerMeterProvider {
uint32_t _lastPoll = 0;

mutable std::mutex _valueMutex;
power_values_t _powerValues;
power_values_t _powerValues = {};

std::array<std::unique_ptr<HttpGetter>, POWERMETER_HTTP_JSON_MAX_VALUES> _httpGetters;

Expand Down
55 changes: 55 additions & 0 deletions include/SPIPortManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include <array>
#include <optional>
#include <string>
#include <driver/spi_master.h>

/**
* SPI# to SPI ID and SPI_HOST mapping
*
* ESP32
* | SPI # | SPI ID | SPI_HOST |
* | 2 | 2 | 1 |
* | 3 | 3 | 2 |
*
* ESP32-S3
* | SPI # | SPI ID | SPI_HOST |
* | 2 | 0 | 1 |
* | 3 | 1 | 2 |
*
* ESP32-C3
* | SPI # | SPI ID | SPI_HOST |
* | 2 | 0 | 1 |
*
*/

class SPIPortManagerClass {
public:
void init();

std::optional<uint8_t> allocatePort(std::string const& owner);
void freePort(std::string const& owner);
spi_host_device_t SPIhostNum(uint8_t spi_num);

private:
// the amount of SPIs available on supported ESP32 chips
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3
static size_t constexpr _num_controllers = 4;
#else
static size_t constexpr _num_controllers = 3;
#endif

#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
static int8_t constexpr _offset_spi_num = -2; // FSPI=0, HSPI=1
static int8_t constexpr _offset_spi_host = 1; // SPI1_HOST=0 but not usable, SPI2_HOST=1 and SPI3_HOST=2, first usable is SPI2_HOST
#else
static int8_t constexpr _offset_spi_num = 0; // HSPI=2, VSPI=3
static int8_t constexpr _offset_spi_host = -1; // SPI1_HOST=0 but not usable, SPI2_HOST=1 and SPI3_HOST=2, first usable is SPI2_HOST
#endif

std::array<std::string, _num_controllers> _ports = { "" };
};

extern SPIPortManagerClass SPIPortManager;
4 changes: 2 additions & 2 deletions include/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@
#define POWERLIMITER_VOLTAGE_LOAD_CORRECTION_FACTOR 0.001
#define POWERLIMITER_RESTART_HOUR -1
#define POWERLIMITER_FULL_SOLAR_PASSTHROUGH_SOC 100
#define POWERLIMITER_FULL_SOLAR_PASSTHROUGH_START_VOLTAGE 100.0
#define POWERLIMITER_FULL_SOLAR_PASSTHROUGH_STOP_VOLTAGE 100.0
#define POWERLIMITER_FULL_SOLAR_PASSTHROUGH_START_VOLTAGE 66.0
#define POWERLIMITER_FULL_SOLAR_PASSTHROUGH_STOP_VOLTAGE 66.0

#define BATTERY_ENABLED false
#define BATTERY_PROVIDER 0 // Pylontech CAN receiver
Expand Down
4 changes: 2 additions & 2 deletions lib/CMT2300a/cmt2300a_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
* @name CMT2300A_InitSpi
* @desc Initializes the CMT2300A SPI interface.
* *********************************************************/
void CMT2300A_InitSpi(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed)
void CMT2300A_InitSpi(const spi_host_device_t spi_host, const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed)
{
cmt_spi3_init(pin_sdio, pin_clk, pin_cs, pin_fcs, spi_speed);
cmt_spi3_init(spi_host, pin_sdio, pin_clk, pin_cs, pin_fcs, spi_speed);
}

/*! ********************************************************
Expand Down
3 changes: 2 additions & 1 deletion lib/CMT2300a/cmt2300a_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <stdint.h>
#include <Arduino.h>
#include <driver/spi_master.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -36,7 +37,7 @@ extern "C" {
#define CMT2300A_GetTickCount() millis()
/* ************************************************************************ */

void CMT2300A_InitSpi(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed);
void CMT2300A_InitSpi(const spi_host_device_t spi_host, const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed);

uint8_t CMT2300A_ReadReg(const uint8_t addr);
void CMT2300A_WriteReg(const uint8_t addr, const uint8_t dat);
Expand Down
5 changes: 3 additions & 2 deletions lib/CMT2300a/cmt2300wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
#include "cmt2300a_params_860.h"
#include "cmt2300a_params_900.h"

CMT2300A::CMT2300A(const uint8_t pin_sdio, const uint8_t pin_clk, const uint8_t pin_cs, const uint8_t pin_fcs, const uint32_t spi_speed)
CMT2300A::CMT2300A(const spi_host_device_t spi_host, const uint8_t pin_sdio, const uint8_t pin_clk, const uint8_t pin_cs, const uint8_t pin_fcs, const uint32_t spi_speed)
{
_spi_host = spi_host;
_pin_sdio = pin_sdio;
_pin_clk = pin_clk;
_pin_cs = pin_cs;
Expand Down Expand Up @@ -266,7 +267,7 @@ void CMT2300A::flush_rx(void)

bool CMT2300A::_init_pins()
{
CMT2300A_InitSpi(_pin_sdio, _pin_clk, _pin_cs, _pin_fcs, _spi_speed);
CMT2300A_InitSpi(_spi_host, _pin_sdio, _pin_clk, _pin_cs, _pin_fcs, _spi_speed);

return true; // assuming pins are connected properly
}
Expand Down
4 changes: 3 additions & 1 deletion lib/CMT2300a/cmt2300wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#pragma once

#include <stdint.h>
#include <driver/spi_master.h>

#define CMT2300A_ONE_STEP_SIZE 2500 // frequency channel step size for fast frequency hopping operation: One step size is 2.5 kHz.
#define FH_OFFSET 100 // value * CMT2300A_ONE_STEP_SIZE = channel frequency offset
Expand All @@ -18,7 +19,7 @@ enum FrequencyBand_t {

class CMT2300A {
public:
CMT2300A(const uint8_t pin_sdio, const uint8_t pin_clk, const uint8_t pin_cs, const uint8_t pin_fcs, const uint32_t _spi_speed = CMT_SPI_SPEED);
CMT2300A(const spi_host_device_t spi_host, const uint8_t pin_sdio, const uint8_t pin_clk, const uint8_t pin_cs, const uint8_t pin_fcs, const uint32_t _spi_speed = CMT_SPI_SPEED);

bool begin(void);

Expand Down Expand Up @@ -128,6 +129,7 @@ class CMT2300A {
*/
bool _init_radio();

spi_host_device_t _spi_host;
int8_t _pin_sdio;
int8_t _pin_clk;
int8_t _pin_cs;
Expand Down
16 changes: 5 additions & 11 deletions lib/CMT2300a/cmt_spi3.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "cmt_spi3.h"
#include <Arduino.h>
#include <driver/spi_master.h>
#include <esp_rom_gpio.h> // for esp_rom_gpio_connect_out_signal

SemaphoreHandle_t paramLock = NULL;
Expand All @@ -9,14 +8,9 @@ SemaphoreHandle_t paramLock = NULL;
} while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS)
#define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock)

// for ESP32 this is the so-called HSPI
// for ESP32-S2/S3/C3 this nomenclature does not really exist anymore,
// it is simply the first externally usable hardware SPI master controller
#define SPI_CMT SPI2_HOST

spi_device_handle_t spi_reg, spi_fifo;

void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed)
void cmt_spi3_init(const spi_host_device_t spi_host, const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed)
{
paramLock = xSemaphoreCreateMutex();

Expand All @@ -43,8 +37,8 @@ void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin
.post_cb = NULL,
};

ESP_ERROR_CHECK(spi_bus_initialize(SPI_CMT, &buscfg, SPI_DMA_DISABLED));
ESP_ERROR_CHECK(spi_bus_add_device(SPI_CMT, &devcfg, &spi_reg));
ESP_ERROR_CHECK(spi_bus_initialize(spi_host, &buscfg, SPI_DMA_DISABLED));
ESP_ERROR_CHECK(spi_bus_add_device(spi_host, &devcfg, &spi_reg));

// FiFo
spi_device_interface_config_t devcfg2 = {
Expand All @@ -61,9 +55,9 @@ void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin
.pre_cb = NULL,
.post_cb = NULL,
};
ESP_ERROR_CHECK(spi_bus_add_device(SPI_CMT, &devcfg2, &spi_fifo));
ESP_ERROR_CHECK(spi_bus_add_device(spi_host, &devcfg2, &spi_fifo));

esp_rom_gpio_connect_out_signal(pin_sdio, spi_periph_signal[SPI_CMT].spid_out, true, false);
esp_rom_gpio_connect_out_signal(pin_sdio, spi_periph_signal[spi_host].spid_out, true, false);
delay(100);
}

Expand Down
3 changes: 2 additions & 1 deletion lib/CMT2300a/cmt_spi3.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#define __CMT_SPI3_H

#include <stdint.h>
#include <driver/spi_master.h>

void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed);
void cmt_spi3_init(const spi_host_device_t spi_host, const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed);

void cmt_spi3_write(const uint8_t addr, const uint8_t dat);
uint8_t cmt_spi3_read(const uint8_t addr);
Expand Down
4 changes: 2 additions & 2 deletions lib/Hoymiles/src/Hoymiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ void HoymilesClass::initNRF(SPIClass* initialisedSpiBus, const uint8_t pinCE, co
_radioNrf->init(initialisedSpiBus, pinCE, pinIRQ);
}

void HoymilesClass::initCMT(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int8_t pin_gpio2, const int8_t pin_gpio3)
void HoymilesClass::initCMT(const spi_host_device_t spi_host, const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int8_t pin_gpio2, const int8_t pin_gpio3)
{
_radioCmt->init(pin_sdio, pin_clk, pin_cs, pin_fcs, pin_gpio2, pin_gpio3);
_radioCmt->init(spi_host, pin_sdio, pin_clk, pin_cs, pin_fcs, pin_gpio2, pin_gpio3);
}

void HoymilesClass::loop()
Expand Down
Loading

0 comments on commit 83ed72e

Please sign in to comment.