Merge pull request #125 from helgeerbe/powerlimiter
Translations for powerlimiter admin; Pylontech CAN Pins in Device manager; other fixes & enhancements
This commit is contained in:
commit
6dd34a8401
@ -271,6 +271,8 @@ This can be achieved by copying one of the [env:....] sections from 'platformio.
|
||||
-DHOYMILES_PIN_CS=5
|
||||
-DVICTRON_PIN_TX=21
|
||||
-DVICTRON_PIN_RX=22
|
||||
-DPYLONTECH_PIN_RX=27
|
||||
-DPYLONTECH_PIN_TX=14
|
||||
```
|
||||
It is recommended to make all changes only in the 'platformio_override.ini', this is your personal copy.
|
||||
You can also change the pins by creating a custom [device profile](docs/DeviceProfiles.md).
|
||||
|
||||
@ -31,6 +31,8 @@ struct PinMapping_t {
|
||||
uint8_t display_reset;
|
||||
uint8_t victron_tx;
|
||||
uint8_t victron_rx;
|
||||
uint8_t battery_rx;
|
||||
uint8_t battery_tx;
|
||||
};
|
||||
|
||||
class PinMappingClass {
|
||||
@ -42,6 +44,7 @@ public:
|
||||
bool isValidNrf24Config();
|
||||
bool isValidEthConfig();
|
||||
bool isValidVictronConfig();
|
||||
bool isValidBatteryConfig();
|
||||
|
||||
private:
|
||||
PinMapping_t _pinMapping;
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
|
||||
class PylontechCanReceiverClass {
|
||||
public:
|
||||
void init();
|
||||
void init(int8_t rx, int8_t tx);
|
||||
void enable();
|
||||
void loop();
|
||||
void parseCanPackets();
|
||||
void mqtt();
|
||||
|
||||
@ -55,6 +55,8 @@ build_flags = ${env.build_flags}
|
||||
-DHOYMILES_PIN_CS=5
|
||||
-DVICTRON_PIN_TX=21
|
||||
-DVICTRON_PIN_RX=22
|
||||
-DPYLONTECH_PIN_RX=27
|
||||
-DPYLONTECH_PIN_TX=14
|
||||
|
||||
|
||||
[env:olimex_esp32_poe]
|
||||
|
||||
@ -64,6 +64,8 @@ PinMappingClass::PinMappingClass()
|
||||
_pinMapping.victron_tx = VICTRON_PIN_TX;
|
||||
_pinMapping.victron_rx = VICTRON_PIN_RX;
|
||||
|
||||
_pinMapping.battery_rx = PYLONTECH_PIN_RX;
|
||||
_pinMapping.battery_tx = PYLONTECH_PIN_TX;
|
||||
}
|
||||
|
||||
PinMapping_t& PinMappingClass::get()
|
||||
@ -119,6 +121,9 @@ bool PinMappingClass::init(const String& deviceMapping)
|
||||
_pinMapping.victron_rx = doc[i]["victron"]["rx"] | VICTRON_PIN_RX;
|
||||
_pinMapping.victron_tx = doc[i]["victron"]["tx"] | VICTRON_PIN_TX;
|
||||
|
||||
_pinMapping.battery_rx = doc[i]["battery"]["rx"] | PYLONTECH_PIN_RX;
|
||||
_pinMapping.battery_tx = doc[i]["battery"]["tx"] | PYLONTECH_PIN_TX;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -146,3 +151,9 @@ bool PinMappingClass::isValidVictronConfig()
|
||||
return _pinMapping.victron_rx > 0
|
||||
&& _pinMapping.victron_tx > 0;
|
||||
}
|
||||
|
||||
bool PinMappingClass::isValidBatteryConfig()
|
||||
{
|
||||
return _pinMapping.battery_rx > 0
|
||||
&& _pinMapping.battery_tx > 0;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ void PowerLimiterClass::init()
|
||||
}
|
||||
|
||||
_consumeSolarPowerOnly = true;
|
||||
_lastCommandSent = 0;
|
||||
_lastCommandSent = 0;
|
||||
_lastLoop = 0;
|
||||
_lastPowerMeterUpdate = 0;
|
||||
_lastRequestedPowerLimit = 0;
|
||||
@ -48,8 +48,6 @@ void PowerLimiterClass::init()
|
||||
|
||||
void PowerLimiterClass::onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total)
|
||||
{
|
||||
MessageOutput.printf("PowerLimiterClass: Received MQTT message on topic: %s\r\n", topic);
|
||||
|
||||
CONFIG_T& config = Configuration.get();
|
||||
|
||||
if (strcmp(topic, config.PowerLimiter_MqttTopicPowerMeter1) == 0) {
|
||||
@ -109,11 +107,10 @@ void PowerLimiterClass::loop()
|
||||
float acPower = inverter->Statistics()->getChannelFieldValue(TYPE_AC, (ChannelNum_t) config.PowerLimiter_InverterChannelId, FLD_PAC);
|
||||
float correctedDcVoltage = dcVoltage + (acPower * config.PowerLimiter_VoltageLoadCorrectionFactor);
|
||||
|
||||
if ((_consumeSolarPowerOnly && isStartThresholdReached(inverter))
|
||||
|| !canUseDirectSolarPower()) {
|
||||
if ((_consumeSolarPowerOnly && isStartThresholdReached(inverter))) {
|
||||
// The battery is full enough again, use the full battery power from now on.
|
||||
_consumeSolarPowerOnly = false;
|
||||
} else if (!_consumeSolarPowerOnly && !isStopThresholdReached(inverter) && canUseDirectSolarPower()) {
|
||||
} else if (!_consumeSolarPowerOnly && isStopThresholdReached(inverter) && canUseDirectSolarPower()) {
|
||||
// The battery voltage dropped too low
|
||||
_consumeSolarPowerOnly = true;
|
||||
}
|
||||
@ -224,7 +221,7 @@ bool PowerLimiterClass::canUseDirectSolarPower()
|
||||
|
||||
uint16_t PowerLimiterClass::getDirectSolarPower()
|
||||
{
|
||||
if (!this->canUseDirectSolarPower()) {
|
||||
if (!canUseDirectSolarPower()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -249,7 +246,7 @@ bool PowerLimiterClass::isStartThresholdReached(std::shared_ptr<InverterAbstract
|
||||
{
|
||||
CONFIG_T& config = Configuration.get();
|
||||
|
||||
// If the Battery interface is enabled, use the SOC value
|
||||
// Check if the Battery interface is enabled and the SOC start threshold is reached
|
||||
if (config.Battery_Enabled
|
||||
&& config.PowerLimiter_BatterySocStartThreshold > 0.0
|
||||
&& (millis() - Battery.stateOfChargeLastUpdate) < 60000
|
||||
@ -270,7 +267,7 @@ bool PowerLimiterClass::isStopThresholdReached(std::shared_ptr<InverterAbstract>
|
||||
{
|
||||
CONFIG_T& config = Configuration.get();
|
||||
|
||||
// If the Battery interface is enabled, use the SOC value
|
||||
// Check if the Battery interface is enabled and the SOC stop threshold is reached
|
||||
if (config.Battery_Enabled
|
||||
&& config.PowerLimiter_BatterySocStopThreshold > 0.0
|
||||
&& (millis() - Battery.stateOfChargeLastUpdate) < 60000
|
||||
|
||||
@ -9,16 +9,21 @@
|
||||
|
||||
PylontechCanReceiverClass PylontechCanReceiver;
|
||||
|
||||
void PylontechCanReceiverClass::init()
|
||||
void PylontechCanReceiverClass::init(int8_t rx, int8_t tx)
|
||||
{
|
||||
CAN.setPins(rx, tx);
|
||||
|
||||
CONFIG_T& config = Configuration.get();
|
||||
|
||||
if (!config.Battery_Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
CAN.setPins(PYLONTECH_PIN_RX, PYLONTECH_PIN_TX);
|
||||
enable();
|
||||
}
|
||||
|
||||
void PylontechCanReceiverClass::enable()
|
||||
{
|
||||
if (!CAN.begin(500E3)) {
|
||||
Hoymiles.getMessageOutput()->println("Starting CAN failed!");
|
||||
}
|
||||
|
||||
@ -108,6 +108,6 @@ void WebApiBatteryClass::onAdminPost(AsyncWebServerRequest* request)
|
||||
request->send(response);
|
||||
|
||||
if (config.Battery_Enabled) {
|
||||
PylontechCanReceiver.init();
|
||||
PylontechCanReceiver.enable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,6 +73,10 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
||||
victronPinObj[F("rx")] = pin.victron_rx;
|
||||
victronPinObj[F("tx")] = pin.victron_tx;
|
||||
|
||||
JsonObject batteryPinObj = curPin.createNestedObject("battery");
|
||||
batteryPinObj[F("rx")] = pin.battery_rx;
|
||||
batteryPinObj[F("tx")] = pin.battery_tx;
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
13
src/main.cpp
13
src/main.cpp
@ -7,6 +7,7 @@
|
||||
#include "InverterSettings.h"
|
||||
#include "MessageOutput.h"
|
||||
#include "VeDirectFrameHandler.h"
|
||||
#include "PylontechCanReceiver.h"
|
||||
#include "MqttHandleDtu.h"
|
||||
#include "MqttHandleHass.h"
|
||||
#include "MqttHandleVedirectHass.h"
|
||||
@ -20,7 +21,6 @@
|
||||
#include "Utils.h"
|
||||
#include "WebApi.h"
|
||||
#include "PowerLimiter.h"
|
||||
#include "PylontechCanReceiver.h"
|
||||
#include "defaults.h"
|
||||
#include <Arduino.h>
|
||||
#include <LittleFS.h>
|
||||
@ -149,8 +149,15 @@ void setup()
|
||||
// Dynamic power limiter
|
||||
PowerLimiter.init();
|
||||
|
||||
// Pylontech / CAN bus
|
||||
PylontechCanReceiver.init();
|
||||
// Initialize Pylontech Battery / CAN bus
|
||||
MessageOutput.println(F("Initialize Pylontech battery interface... "));
|
||||
if (PinMapping.isValidBatteryConfig()) {
|
||||
MessageOutput.printf("Pylontech Battery rx = %d, tx = %d\r\n", pin.battery_rx, pin.battery_tx);
|
||||
PylontechCanReceiver.init(pin.battery_rx, pin.battery_tx);
|
||||
MessageOutput.println(F("done"));
|
||||
} else {
|
||||
MessageOutput.println(F("Invalid pin config"));
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
||||
@ -447,6 +447,12 @@
|
||||
"Save": "@:dtuadmin.Save"
|
||||
},
|
||||
"powerlimiteradmin": {
|
||||
"PowerLimiterSettings": "Power Limiter Einstellungen",
|
||||
"PowerLimiterConfiguration": "Power Limiter Konfiguration",
|
||||
"General": "Allgemein",
|
||||
"Enable": "Aktiviert",
|
||||
"EnableSolarPasstrough": "Aktiviere Solar Pass-trough",
|
||||
"SolarpasstroughInfo": "Diese Einstellung aktiviert die direkte Weitergabe der aktuell vom Laderegler gemeldeten Solarleistung an den Wechselrichter um eine unnötige Speicherung zu vermeiden und die Energieverluste zu minimieren.",
|
||||
"InverterId": "Wechselrichter ID",
|
||||
"InverterIdHint": "Wähle den Wechselrichter an dem die Batterie hängt.",
|
||||
"InverterChannelId": "Kanal ID",
|
||||
@ -454,8 +460,23 @@
|
||||
"TargetPowerConsumption": "Erlaubter Stromverbrauch",
|
||||
"TargetPowerConsumptionHint": "Angestrebter erlaubter Stromverbrauch.",
|
||||
"TargetPowerConsumptionHysteresis": "Hysterese für den Zielstromverbrauch",
|
||||
"TargetPowerConsumptionHysteresisHint": "Wert um den der Zielstromverbrauch schwanken darf, ohne dass nachgeregelt wird."
|
||||
|
||||
"TargetPowerConsumptionHysteresisHint": "Wert um den der Zielstromverbrauch schwanken darf, ohne dass nachgeregelt wird.",
|
||||
"LowerPowerLimit": "Unteres Leistungslimit",
|
||||
"UpperPowerLimit": "Oberes Leistungslimit",
|
||||
"PowerMeters": "Leistungsmesser - MQTT",
|
||||
"MqttTopicPowerMeter1": "MQTT topic - Power meter #1",
|
||||
"MqttTopicPowerMeter2": "MQTT topic - Power meter #2 (Optional)",
|
||||
"MqttTopicPowerMeter3": "MQTT topic - Power meter #3 (Optional)",
|
||||
"BatterySocStartThreshold": "Akku SOC - Start",
|
||||
"BatterySocStopThreshold": "Akku SOC - Stop",
|
||||
"VoltageStartThreshold": "DC Spannung - Start",
|
||||
"VoltageStopThreshold": "DC Spannung - Stop",
|
||||
"VoltageLoadCorrectionFactor": "DC Spannung - Lastkorrekturfaktor",
|
||||
"BatterySocInfo": "<b>Hinweis:</b> Der Battery SOC (State of charge) -Wert kann nur benutzt werden wenn das Battery CAN Bus Interface aktiviert ist. Wenn die Batterie innerhalb der letzten Minute keine Werte geschickt hat, werden als Fallback-Option die Spannungseinstellungen verwendet.",
|
||||
"InverterIsBehindPowerMeter": "Welchselrichter ist hinter Leistungsmesser",
|
||||
"Battery": "DC / Akku",
|
||||
"VoltageLoadCorrectionInfo": "<b>Hinweis:</b> Wenn Leistung von der Batterie abgegeben wird, bricht normalerweise die Spannung etwas ein. Damit nicht vorzeitig der Wechelrichter ausgeschaltet wird sobald der \"Stop\"-Schwellenwert erreicht wird, wird der hier angegebene Korrekturfaktor mit einberechnet. Korrigierte Spannung = DC Spannung + (Aktuelle Leistung (W) + Korrekturfaktor).",
|
||||
"Save": "@:dtuadmin.Save"
|
||||
},
|
||||
"batteryadmin": {
|
||||
"BatterySettings": "Batterie Einstellungen",
|
||||
|
||||
@ -451,7 +451,7 @@
|
||||
"PowerLimiterConfiguration": "Power Limiter Configuration",
|
||||
"General": "General",
|
||||
"Enable": "Enable",
|
||||
"EnableSolarPasstrough": "Enable Solar Passtrough",
|
||||
"EnableSolarPasstrough": "Enable Solar-Passtrough",
|
||||
"SolarpasstroughInfo": "When the sun is shining, this setting enables the sychronization of the inverter limit with the current solar power of the Victron MPPT charger. This optimizes battery degradation and loses.",
|
||||
"InverterId": "Inverter ID",
|
||||
"InverterIdHint": "Select proper inverter ID where battery is connected to.",
|
||||
@ -461,12 +461,12 @@
|
||||
"TargetPowerConsumptionHint": "Set the grid power consumption the limiter tries to achieve.",
|
||||
"TargetPowerConsumptionHysteresis": "Hysteresis for power consumption",
|
||||
"TargetPowerConsumptionHysteresisHint": "Value around which the target power consumption fluctuates without readjustment.",
|
||||
"LowerPowerLimit": "Lower power limit / continuous feed",
|
||||
"LowerPowerLimit": "Lower power limit",
|
||||
"UpperPowerLimit": "Upper power limit",
|
||||
"PowerMeters": "Power meters - MQTT",
|
||||
"MqttTopicPowerMeter1": "MQTT topic - Power meter #1",
|
||||
"MqttTopicPowerMeter2": "MQTT topic - Power meter #2",
|
||||
"MqttTopicPowerMeter3": "MQTT topic - Power meter #3",
|
||||
"MqttTopicPowerMeter2": "MQTT topic - Power meter #2 (optional)",
|
||||
"MqttTopicPowerMeter3": "MQTT topic - Power meter #3 (optional)",
|
||||
"BatterySocStartThreshold": "Battery SOC - Start threshold",
|
||||
"BatterySocStopThreshold": "Battery SOC - Stop threshold",
|
||||
"VoltageStartThreshold": "DC Voltage - Start threshold",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user