Skip to content

Commit

Permalink
evse.h, evse.cpp, glcd.cpp: Add MaxSumMains for EU capacity rate limi…
Browse files Browse the repository at this point in the history
…ting
  • Loading branch information
dingo35 committed Dec 15, 2023
1 parent fe93352 commit 135abc9
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
11 changes: 7 additions & 4 deletions SmartEVSE-3/include/evse.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ extern RemoteDebug Debug;

#define ICAL 1024 // Irms Calibration value (for Current transformers)
#define MAX_MAINS 25 // max Current the Mains connection can supply
#define MAX_SUMMAINS 600 // only used for capacity rate limiting, max current over the sum of all phases
#define MAX_CURRENT 13 // max charging Current for the EV
#define MIN_CURRENT 6 // minimum Current the EV will accept
#define MODE 0 // Normal EVSE mode
Expand Down Expand Up @@ -332,9 +333,10 @@ extern RemoteDebug Debug;
#define MENU_C2 38
#define MENU_MAX_TEMP 39
#define MENU_MODEM 40
#define MENU_OFF 41 // so access bit is reset and charging stops when pressing < button 2 seconds
#define MENU_ON 42 // so access bit is set and charging starts when pressing > button 2 seconds
#define MENU_EXIT 43
#define MENU_SUMMAINS 41
#define MENU_OFF 42 // so access bit is reset and charging stops when pressing < button 2 seconds
#define MENU_ON 43 // so access bit is set and charging starts when pressing > button 2 seconds
#define MENU_EXIT 44

#define MENU_STATE 50

Expand Down Expand Up @@ -462,7 +464,7 @@ const struct {
{"EV ADDR", "Address of EV electric meter", MIN_METER_ADDRESS, MAX_METER_ADDRESS, EV_METER_ADDRESS},

// System configuration
/* Key, LCD, Desc, Min, Max, Default */
/* LCD, Desc, Min, Max, Default */
{"MODE", "Normal, Smart or Solar EVSE mode", 0, 2, MODE},
{"CIRCUIT", "EVSE Circuit max Current", 10, 160, MAX_CIRCUIT},
{"GRID", "Grid type to which the Sensorbox is connected", 0, 1, GRID},
Expand Down Expand Up @@ -492,6 +494,7 @@ const struct {
{"CONTACT2","Contactor2 (C2) behaviour", 0, sizeof(StrEnableC2) / sizeof(StrEnableC2[0])-1, ENABLE_C2},
{"MAX TEMP","Maximum temperature for the EVSE module", 40, 75, MAX_TEMPERATURE},
{"MODEM", "Is an ISO15118 modem installed (experimental)", 0, 1, NOTPRESENT},
{"SUMMAINS","Capacity Rate limit on sum of MAINS Current (A)", 10, 600, MAX_SUMMAINS},
{"", "Hold 2 sec to stop charging", 0, 0, 0},
{"", "Hold 2 sec to start charging", 0, 0, 0},

Expand Down
46 changes: 43 additions & 3 deletions SmartEVSE-3/src/evse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ const char StrRFIDStatusWeb[8][20] = {"Ready to read card","Present", "Card Stor

// The following data will be updated by eeprom/storage data at powerup:
uint16_t MaxMains = MAX_MAINS; // Max Mains Amps (hard limit, limited by the MAINS connection) (A)
uint16_t MaxSumMains = MAX_SUMMAINS; // Max Mains Amps summed over all 3 phases, limit used by EU capacity rate
// see https://github.com/serkri/SmartEVSE-3/issues/215
uint16_t MaxCurrent = MAX_CURRENT; // Max Charge current (A)
uint16_t MinCurrent = MIN_CURRENT; // Minimal current the EV is happy with (A)
uint16_t ICal = ICAL; // CT calibration value
Expand Down Expand Up @@ -885,6 +887,10 @@ char IsCurrentAvailable(void) {
if (Imeasured_EV > ((MaxCircuit - MinCurrent) * 10)) { // There should be at least 6A available
return 0; // Not enough current available!, return with error
}
//assume the current should be available on all 3 phases
if (Isum > (MaxSumMains - (MinCurrent * 3)) * 10) { // To guard capacity rate
return 0; // Not enough current available!, return with error
}
} else { // at least one active EVSE
ActiveEVSE++; // Do calculations with one more EVSE
Baseload = Imeasured - TotalCurrent; // Calculate Baseload (load without any active EVSE)
Expand All @@ -907,6 +913,10 @@ char IsCurrentAvailable(void) {
if ((ActiveEVSE * (MinCurrent * 10) + Baseload) > (MaxCircuit * 10) - Baseload_EV) {
return 0; // Not enough current available!, return with error
}
//assume the current should be available on all 3 phases
if ((3 * ActiveEVSE * (MinCurrent * 10) + Isum) > (MaxSumMains * 10)) {
return 0; // Not enough current available!, return with error
}

}

Expand Down Expand Up @@ -984,12 +994,16 @@ void CalcBalancedCurrent(char mod) {
IsetBalanced = ChargeCurrent; // No Load Balancing in Normal Mode. Set current to ChargeCurrent (fix: v2.05)
if (BalancedLeft && mod) { // Only if we have active EVSE's and New EVSE charging
// Set max combined charge current to MaxMains - Baseload, or MaxCircuit - Baseload_EV if that is less
IsetBalanced = min((MaxMains * 10) - Baseload, (MaxCircuit * 10 ) - Baseload_EV);
IsetBalanced = min((MaxMains * 10) - Baseload, (MaxCircuit * 10 ) - Baseload_EV); //TODO: why are we checking MaxMains and MaxCircuit while we are in Normal mode?
//TODO: capacity rate limiting here?
}
} //end MODE_NORMAL
else { // start MODE_SOLAR || MODE_SMART
// adapt IsetBalanced in Smart Mode, and ensure the MaxMains/MaxCircuit settings for Solar
Idifference = min((MaxMains * 10) - Imeasured, (MaxCircuit * 10) - Imeasured_EV);

uint8_t Temp_Phases;
Temp_Phases = (Nr_Of_Phases_Charging ? Nr_Of_Phases_Charging : 3); // in case nr of phases not detected, assume 3
Idifference = min((MaxMains * 10) - Imeasured, min((MaxCircuit * 10) - Imeasured_EV, ((MaxSumMains * 10) - Isum)/Temp_Phases));
if (!mod) { // no new EVSE's charging
// For Smart mode, no new EVSE asking for current
// But for Solar mode we _also_ have to guard MaxCircuit and Maxmains!
Expand Down Expand Up @@ -1052,7 +1066,7 @@ void CalcBalancedCurrent(char mod) {
else { // MODE_SMART
// New EVSE charging, and only if we have active EVSE's
if (mod && BalancedLeft) { // Set max combined charge current to MaxMains - Baseload
IsetBalanced = min((MaxMains * 10) - Baseload, (MaxCircuit * 10 ) - Baseload_EV);
IsetBalanced = min((MaxMains * 10) - Baseload, min((MaxCircuit * 10 ) - Baseload_EV, ((MaxSumMains * 10) - Isum)/3)); //assume the current should be available on all 3 phases
}
} //end MODE_SMART
} // end MODE_SOLAR || MODE_SMART
Expand Down Expand Up @@ -1305,6 +1319,9 @@ uint8_t setItemValue(uint8_t nav, uint16_t val) {
case MENU_MAINS:
MaxMains = val;
break;
case MENU_SUMMAINS:
MaxSumMains = val;
break;
case MENU_MIN:
MinCurrent = val;
break;
Expand Down Expand Up @@ -1457,6 +1474,8 @@ uint16_t getItemValue(uint8_t nav) {
return LoadBl;
case MENU_MAINS:
return MaxMains;
case MENU_SUMMAINS:
return MaxSumMains;
case MENU_MIN:
return MinCurrent;
case MENU_MAX:
Expand Down Expand Up @@ -2290,6 +2309,13 @@ void mqtt_receive_callback(const String &topic, const String &payload) {
OverrideCurrent = RequestedCurrent;
}
}
} else if (topic == MQTTprefix + "/Set/CurrentMaxSumMains") {
uint16_t RequestedCurrent = payload.toInt();
if (RequestedCurrent == 0) {
MaxSumMains = 0;
} else if (RequestedCurrent >= (10 * 10) && RequestedCurrent <= (600 * 10)) {
MaxSumMains = RequestedCurrent;
}
} else if (topic == MQTTprefix + "/Set/CPPWMOverride") {
int pwm = payload.toInt();
if (pwm == -1) {
Expand Down Expand Up @@ -3426,6 +3452,7 @@ void read_settings(bool write) {
Access_bit = preferences.getUChar("Access", Default_Access_bit);
LoadBl = preferences.getUChar("LoadBl", LOADBL);
MaxMains = preferences.getUShort("MaxMains", MAX_MAINS);
MaxSumMains = preferences.getUShort("MaxSumMains", MAX_SUMMAINS);
MaxCurrent = preferences.getUShort("MaxCurrent", MAX_CURRENT);
MinCurrent = preferences.getUShort("MinCurrent", MIN_CURRENT);
MaxCircuit = preferences.getUShort("MaxCircuit", MAX_CIRCUIT);
Expand Down Expand Up @@ -3496,6 +3523,7 @@ void write_settings(void) {
preferences.putUChar("Access", Access_bit);
preferences.putUChar("LoadBl", LoadBl);
preferences.putUShort("MaxMains", MaxMains);
preferences.putUShort("MaxSumMains", MaxSumMains);
preferences.putUShort("MaxCurrent", MaxCurrent);
preferences.putUShort("MinCurrent", MinCurrent);
preferences.putUShort("MaxCircuit", MaxCircuit);
Expand Down Expand Up @@ -3767,6 +3795,7 @@ void StartwebServer(void) {
doc["settings"]["current_min"] = MinCurrent;
doc["settings"]["current_max"] = MaxCurrent;
doc["settings"]["current_main"] = MaxMains;
doc["settings"]["current_max_sum_mains"] = MaxSumMains;
doc["settings"]["solar_max_import"] = ImportCurrent;
doc["settings"]["solar_start_current"] = StartCurrent;
doc["settings"]["solar_stop_time"] = StopTime;
Expand Down Expand Up @@ -3865,6 +3894,17 @@ void StartwebServer(void) {
}
}

if(request->hasParam("current_max_sum_mains")) {
int current = request->getParam("current_max_sum_mains")->value().toInt();
if(current >= 10 && current <= 600) {
MaxSumMains = current;
doc["current_max_sum_mains"] = MaxSumMains;
write_settings();
} else {
doc["current_max_sum_mains"] = "Value not allowed!";
}
}

if(request->hasParam("disable_override_current")) {
OverrideCurrent = 0;
doc["disable_override_current"] = "OK";
Expand Down
2 changes: 2 additions & 0 deletions SmartEVSE-3/src/glcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ const char * getMenuItemOption(uint8_t nav) {
case MENU_LOADBL:
return StrLoadBl[LoadBl];
case MENU_MAINS:
case MENU_SUMMAINS:
case MENU_MIN:
case MENU_MAX:
case MENU_CIRCUIT:
Expand Down Expand Up @@ -978,6 +979,7 @@ uint8_t getMenuItems (void) {
MenuItems[m++] = MENU_WIFI; // Wifi Disabled / Enabled / Portal
MenuItems[m++] = MENU_MAX_TEMP;
MenuItems[m++] = MENU_MODEM;
MenuItems[m++] = MENU_SUMMAINS;
MenuItems[m++] = MENU_EXIT;

return m;
Expand Down

0 comments on commit 135abc9

Please sign in to comment.