Skip to content

Commit

Permalink
Dynamic power control and more power control modes on the Huawei PSU
Browse files Browse the repository at this point in the history
  • Loading branch information
MalteSchm committed Jul 1, 2023
1 parent 2223afa commit e279ce0
Show file tree
Hide file tree
Showing 17 changed files with 360 additions and 53 deletions.
14 changes: 14 additions & 0 deletions README_onBattery.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,20 @@ Other settings are:
#### Power Limiter States
![PowerLimiterInverterStates](https://github.com/helgeerbe/OpenDTU-OnBattery/blob/development/docs/PowerLimiterInverterStates.png)

### Huawei PSU

The Huawei PSU can be used to charge a battery. This can be be useful if an external (AC) connected solar system shall be utilized or if variable energy prices should be exploited.

Some points for consideration are:
* Make sure to consider the PSU voltage range when selecting the battery voltage as lower voltages <42V are not supported.
* The PSU runs a noisy fan and it is therefore desireable to switch it off when not being used. Some users have found that switching the slot detect pins with a relay accomplishes this. A GPIO pin is made available from the ESP to turn the PSU on/off

#### Operation modes

openDTU-onBattery supports three operation modes for the Huawei PSU:
1. Fully manual - In this mode the PSU needs to be turned on/off externally using MQTT and voltage and current limits need to be provided. See [MQTT Documentation](docs/MQTT_Topics.md) for details on these commands
2. Manual with auto power on / off - In this mode the PSU is turned on when a current limit > 1A is set. If the current limit is < 1A for some time the PSU is turned off. Current and voltage limits need to be provided externally using MQTT. See [MQTT Documentation](docs/MQTT_Topics.md) for details on these commands.
3. Automatic - In this mode the PSU power is controlled by the Power Meter and information provided in the web-interface. If excess power is present the PSU is turned on. The voltage limit is set as per web-interface and the current limit is set so that the maximum PSU output power equals the Power Meter value. Minium and maximum PSU power levels as configured in the web-interface are respected in this process. The PSU is turned off if the output current is limited and the output power drops below the minium power level. This will disable automatic mode until the battery is discharged below the start voltage level (set in the web-interface). This mode can be enabled using the web-interface and MQTT. See [MQTT Documentation](docs/MQTT_Topics.md)

## Troubleshooting

Expand Down
2 changes: 1 addition & 1 deletion docs/MQTT_Topics.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ cmd topics are used to set values. Status topics are updated from values set in
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
| huawei/cmd/limit_online_voltage | W | Online voltage (i.e. CAN bus connected) | Volt (V) |
| huawei/cmd/limit_online_current | W | Online current (i.e. CAN bus connected) | Ampere (A) |
| huawei/cmd/power | W | Controls output pin GPIO to drive solid state relais | 0 / 1 |
| huawei/cmd/mode | W | Controls GPIO output pin to switch slot detect | 0 (off) / 1 (on) / 2 (set automatically depending on online_current value) / 3 (set automatically based on Power Meter reading ) |
| huawei/data_age | R | How old the data is | Seconds |
| huawei/input_voltage | R | Input voltage | Volt (V) |
| huawei/input_current | R | Input current | Ampere (A) |
Expand Down
5 changes: 5 additions & 0 deletions include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ struct CONFIG_T {

bool Battery_Enabled;
bool Huawei_Enabled;
bool Huawei_Auto_Power_Enabled;
float Huawei_Auto_Power_Voltage_Limit;
float Huawei_Auto_Power_Enable_Voltage_Limit;
float Huawei_Auto_Power_Lower_Power_Limit;
float Huawei_Auto_Power_Upper_Power_Limit;

char Security_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
bool Security_AllowReadonly;
Expand Down
35 changes: 27 additions & 8 deletions include/Huawei_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@
#define R48xx_DATA_OUTPUT_CURRENT 0x81
#define R48xx_DATA_OUTPUT_CURRENT1 0x82

#define HUAWEI_MODE_OFF 0
#define HUAWEI_MODE_ON 1
#define HUAWEI_MODE_AUTO_EXT 2
#define HUAWEI_MODE_AUTO_INT 3

// Wait time/current before shuting down the PSU / charger
// This is set to allow the fan to run for some time
#define HUAWEI_AUTO_MODE_SHUTDOWN_DELAY 60000
#define HUAWEI_AUTO_MODE_SHUTDOWN_CURRENT 1.0

struct RectifierParameters_t {
float input_voltage;
float input_frequency;
Expand All @@ -72,24 +82,33 @@ class HuaweiCanClass {
void init(uint8_t huawei_miso, uint8_t huawei_mosi, uint8_t huawei_clk, uint8_t huawei_irq, uint8_t huawei_cs, uint8_t huawei_power);
void loop();
void setValue(float in, uint8_t parameterType);
void setPower(bool power);
void setMode(uint8_t mode);

RectifierParameters_t * get();
uint32_t getLastUpdate();
bool getAutoPowerStatus();

private:
void sendRequest();
void onReceive(uint8_t* frame, uint8_t len);

uint32_t previousMillis;
uint32_t lastUpdate;
RectifierParameters_t _rp;

SPIClass *spi;
MCP_CAN *CAN;
uint8_t _huawei_irq;
uint8_t _huawei_power;
bool initialized = false;
bool _initialized = false;
uint8_t _huawei_irq; // IRQ pin
uint8_t _huawei_power; // Power pin
uint8_t _mode = HUAWEI_MODE_AUTO_EXT;

RectifierParameters_t _rp;

uint32_t _lastUpdateReceivedMillis; // Timestamp for last data seen from the PSU
uint32_t _nextRequestMillis = 0; // When to send next data request to PSU
uint32_t _nextAutoModePeriodicIntMillis; // When to send the next output volume request in Automatic mode
uint32_t _lastPowerMeterUpdateReceivedMillis; // Timestamp of last power meter value
uint32_t _outputCurrentOnSinceMillis; // Timestamp since when the PSU was idle at zero amps
bool _newOutputPowerReceived = false;
uint8_t _autoPowerEnabled = false;
bool _autoPowerActive = false;
};

extern HuaweiCanClass HuaweiCan;
2 changes: 1 addition & 1 deletion include/PowerLimiter.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class PowerLimiterClass {
void init();
void loop();
uint8_t getPowerLimiterState();
int32_t getLastRequestedPowewrLimit();
int32_t getLastRequestedPowerLimit();
void setMode(uint8_t mode);
bool getMode();
void calcNextInverterRestart();
Expand Down
4 changes: 4 additions & 0 deletions include/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,7 @@
#define BATTERY_ENABLED false

#define HUAWEI_ENABLED false
#define HUAWEI_AUTO_POWER_VOLTAGE_LIMIT 42.0
#define HUAWEI_AUTO_POWER_ENABLE_VOLTAGE_LIMIT 42.0
#define HUAWEI_AUTO_POWER_LOWER_POWER_LIMIT 150
#define HUAWEI_AUTO_POWER_UPPER_POWER_LIMIT 2000
10 changes: 10 additions & 0 deletions src/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ bool ConfigurationClass::write()

JsonObject huawei = doc.createNestedObject("huawei");
huawei["enabled"] = config.Huawei_Enabled;
huawei["auto_power_enabled"] = config.Huawei_Auto_Power_Enabled;
huawei["voltage_limit"] = config.Huawei_Auto_Power_Voltage_Limit;
huawei["enable_voltage_limit"] = config.Huawei_Auto_Power_Enable_Voltage_Limit;
huawei["lower_power_limit"] = config.Huawei_Auto_Power_Lower_Power_Limit;
huawei["upper_power_limit"] = config.Huawei_Auto_Power_Upper_Power_Limit;

// Serialize JSON to file
if (serializeJson(doc, f) == 0) {
Expand Down Expand Up @@ -374,6 +379,11 @@ bool ConfigurationClass::read()

JsonObject huawei = doc["huawei"];
config.Huawei_Enabled = huawei["enabled"] | HUAWEI_ENABLED;
config.Huawei_Auto_Power_Enabled = huawei["auto_power_enabled"] | false;
config.Huawei_Auto_Power_Voltage_Limit = huawei["voltage_limit"] | HUAWEI_AUTO_POWER_VOLTAGE_LIMIT;
config.Huawei_Auto_Power_Enable_Voltage_Limit = huawei["enable_voltage_limit"] | HUAWEI_AUTO_POWER_ENABLE_VOLTAGE_LIMIT;
config.Huawei_Auto_Power_Lower_Power_Limit = huawei["lower_power_limit"] | HUAWEI_AUTO_POWER_LOWER_POWER_LIMIT;
config.Huawei_Auto_Power_Upper_Power_Limit = huawei["upper_power_limit"] | HUAWEI_AUTO_POWER_UPPER_POWER_LIMIT;

f.close();
return true;
Expand Down
Loading

0 comments on commit e279ce0

Please sign in to comment.