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

Adding support for smartEVSE #129

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
52 changes: 23 additions & 29 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ lib_deps =
[email protected]
Micro [email protected]
[email protected]
[email protected].2
[email protected].3
[email protected]
[email protected]
[email protected]
Expand Down Expand Up @@ -219,31 +219,6 @@ framework = arduino, espidf

# export PLATFORMIO_UPLOAD_PORT=172.16.0.157
# export PLATFORMIO_UPLOAD_FLAGS="-p 3232"
[env:openevse_huzzah32_dev]
platform = ${common.platform_esp32}
board = featheresp32
framework = arduino
lib_deps = ${common.lib_deps}
src_build_flags =
${common.version}.dev
${common.src_build_flags}
${common.src_build_flags_esp32}
-DWIFI_LED=13
-DWIFI_LED_ON_STATE=HIGH
-DWIFI_BUTTON=0
-DWIFI_BUTTON_PRESSED_STATE=LOW
-DRAPI_PORT=Serial
-DDEBUG_PORT=Serial2
-DSERIAL_RX_PULLUP_PIN=3
-DENABLE_DEBUG
build_flags =
${common.build_flags}
${common.build_flags_esp32}
upload_speed = 921600
monitor_speed = 115200
extra_scripts = ${common.extra_scripts}
board_build.partitions = ${common.build_partitions_esp32}

[env:openevse_huzzah32]
platform = ${common.platform_esp32}
board = featheresp32
Expand All @@ -257,9 +232,14 @@ src_build_flags =
-DWIFI_LED_ON_STATE=HIGH
-DWIFI_BUTTON=0
-DWIFI_BUTTON_PRESSED_STATE=LOW
-DRAPI_PORT=Serial
-DDEBUG_PORT=Serial2
-DSERIAL_RX_PULLUP_PIN=3
-DRAPI_PORT=Serial1
-DRAPI_PORT_RX=GPIO_NUM_34
-DRAPI_PORT_RX_PULLUP
-DRAPI_PORT_TX=GPIO_NUM_25
-DRAPI_PORT_RESET=GPIO_NUM_26
-DRAPI_PORT_RESET_ACTIVELOW
-DDEBUG_PORT=Serial
-DSMARTEVSE
build_flags =
${common.build_flags}
${common.build_flags_esp32}
Expand All @@ -268,6 +248,20 @@ monitor_speed = 115200
extra_scripts = ${common.extra_scripts}
board_build.partitions = ${common.build_partitions_esp32}

[env:openevse_huzzah32_dev]
extends = env:openevse_huzzah32
src_build_flags = ${env:openevse_huzzah32.src_build_flags} ${common.debug_flags_esp32}

[env:openevse_huzzah32_ota]
extends = env:openevse_huzzah32
upload_protocol = espota
upload_port = openevse.local

[env:openevse_huzzah32_dev_ota]
extends = env:openevse_huzzah32_dev
upload_protocol = espota
upload_port = openevse.local

[env:openevse_huzzah32_idf]
extends = env:openevse_huzzah32
framework = arduino, espidf
Expand Down
4 changes: 3 additions & 1 deletion src/app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ uint32_t flags;
String ohm;

// Divert settings
String divert_feed_type;
double divert_PV_ratio;
double divert_attack_smoothing_factor;
double divert_decay_smoothing_factor;
Expand Down Expand Up @@ -110,6 +111,7 @@ ConfigOpt *opts[] =
new ConfigOptDefenition<String>(ohm, "", "ohm", "o"),

// Divert settings
new ConfigOptDefenition<String>(divert_feed_type, "grid_ie", "divert_feed_type", "dft"),
new ConfigOptDefenition<double>(divert_PV_ratio, 1.1, "divert_PV_ratio", "dpr"),
new ConfigOptDefenition<double>(divert_attack_smoothing_factor, 0.4, "divert_attack_smoothing_factor", "da"),
new ConfigOptDefenition<double>(divert_decay_smoothing_factor, 0.05, "divert_decay_smoothing_factor", "dd"),
Expand Down Expand Up @@ -185,7 +187,7 @@ void config_changed(String name)
mqtt_restart();
} else if(name.startsWith("emoncms_")) {
emoncms_updated = true;
} else if(name == "divert_enabled" || name == "charge_mode") {
} else if(name == "divert_enabled" || name == "charge_mode" || name == "divert_feed_type") {
DBUGVAR(config_divert_enabled());
DBUGVAR(config_charge_mode());
divertmode_update((config_divert_enabled() && 1 == config_charge_mode()) ? DIVERT_MODE_ECO : DIVERT_MODE_NORMAL);
Expand Down
1 change: 1 addition & 0 deletions src/app_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern String mqtt_announce_topic;
extern String time_zone;

// Divert settings
extern String divert_feed_type;
extern double divert_PV_ratio;
extern double divert_attack_smoothing_factor;
extern double divert_decay_smoothing_factor;
Expand Down
25 changes: 23 additions & 2 deletions src/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,32 @@
StreamSpy SerialDebug(DEBUG_PORT);
StreamSpy SerialEvse(RAPI_PORT);

#ifndef DEBUG_PORT_RX
#define DEBUG_PORT_RX -1
#endif

#ifndef DEBUG_PORT_TX
#define DEBUG_PORT_TX -1
#endif

#ifndef RAPI_PORT_RX
#define RAPI_PORT_RX -1
#endif

#ifndef RAPI_PORT_TX
#define RAPI_PORT_TX -1
#endif

void debug_setup()
{
DEBUG_PORT.begin(115200);
DEBUG_PORT.begin(115200, SERIAL_8N1, DEBUG_PORT_RX, DEBUG_PORT_TX);
SerialDebug.begin(2048);

RAPI_PORT.begin(115200);
RAPI_PORT.begin(115200, SERIAL_8N1, RAPI_PORT_RX, RAPI_PORT_TX);
SerialEvse.begin(2048);

#if RAPI_PORT_RX != -1 && defined(RAPI_PORT_RX_PULLUP)
// https://forums.adafruit.com/viewtopic.php?f=57&t=153553&p=759890&hilit=esp32+serial+pullup#p769168
pinMode(RAPI_PORT_RX, INPUT_PULLUP);
#endif
}
70 changes: 38 additions & 32 deletions src/divert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,45 +67,51 @@ time_t __attribute__((weak)) divertmode_get_time()
// function called when divert mode is changed
void divertmode_update(byte newmode)
{
DBUGF("Set divertmode: %d", newmode);
DBUGF("Set divertmode: %d %s", newmode, divert_feed_type.c_str());
if(divertmode != newmode)
{
divertmode = newmode;

// restore max charge current if normal mode or zero if eco mode
switch(divertmode)
{
case DIVERT_MODE_NORMAL:
// Restore the max charge current
rapiSender.sendCmdSync(String(F("$SC ")) + String(max_charge_current));
DBUGF("Restore max I: %d", max_charge_current);
break;

case DIVERT_MODE_ECO:
charge_rate = 0;
available_current = 0;
smoothed_available_current = 0;
min_charge_end = 0;

// Read the current charge current, assume this is the max set by the user
if(0 == rapiSender.sendCmdSync(F("$GE"))) {
max_charge_current = String(rapiSender.getToken(1)).toInt();
DBUGF("Read max I: %d", max_charge_current);
}
if(OPENEVSE_STATE_SLEEPING != state)
{
if(0 == rapiSender.sendCmdSync(config_pause_uses_disabled() ? F("$FD") : F("$FS")))
if (divert_feed_type == "internal") {
rapiSender.sendCmdSync(String(F("$SX ")) + String((divertmode==DIVERT_MODE_NORMAL)?1:2));
}
else {

// restore max charge current if normal mode or zero if eco mode
switch(divertmode)
{
case DIVERT_MODE_NORMAL:
// Restore the max charge current
rapiSender.sendCmdSync(String(F("$SC ")) + String(max_charge_current));
DBUGF("Restore max I: %d", max_charge_current);
break;

case DIVERT_MODE_ECO:
charge_rate = 0;
available_current = 0;
smoothed_available_current = 0;
min_charge_end = 0;

// Read the current charge current, assume this is the max set by the user
if(0 == rapiSender.sendCmdSync(F("$GE"))) {
max_charge_current = String(rapiSender.getToken(1)).toInt();
DBUGF("Read max I: %d", max_charge_current);
}
if(OPENEVSE_STATE_SLEEPING != state)
{
DBUGLN(F("Divert activated, entered sleep mode"));
divert_active = false;
if(0 == rapiSender.sendCmdSync(config_pause_uses_disabled() ? F("$FD") : F("$FS")))
{
DBUGLN(F("Divert activated, entered sleep mode"));
divert_active = false;
}
}
}
break;
break;

default:
return;
default:
return;
}
}

StaticJsonDocument<128> event;
event["divertmode"] = divertmode;
event["divert_active"] = divert_active;
Expand Down Expand Up @@ -135,7 +141,7 @@ void divert_update_state()
}

// If divert mode = Eco (2)
if (divertmode == DIVERT_MODE_ECO)
if (divertmode == DIVERT_MODE_ECO && divert_feed_type != "internal")
{
int current_charge_rate = charge_rate;

Expand Down
74 changes: 72 additions & 2 deletions src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,14 @@ int espfree = 0;

int rapi_command = 1;

double amp = 0; // OpenEVSE Current Sensor
double amp = 0; // OpenEVSE Current Sensor
double voltage = DEFAULT_VOLTAGE; // Voltage from OpenEVSE or MQTT

double amp_phase_sys[3] = {0,0,0}; // SmartEVSE system current per phase
double amp_phase[3] = {0,0,0}; // SmartEVSE EV current per phase
double volt_phase[3] = {0,0,0}; // SmartEVSE voltage per phase


double temp1 = 0; // Sensor DS3232 Ambient
bool temp1_valid = false;
double temp2 = 0; // Sensor MCP9808 Ambiet
Expand All @@ -50,6 +56,12 @@ long pilot = 0; // OpenEVSE Pilot Setting
long state = OPENEVSE_STATE_STARTING; // OpenEVSE State
long elapsed = 0; // Elapsed time (only valid if charging)

int smartevse_mode = SMARTEVSE_MODE_NORMAL; // SmartEVSE charge mode (NORMAL, SMART, SOLAR)

#ifdef ENABLE_LEGACY_API
String estate = "Unknown"; // Common name for State
#endif

// Defaults OpenEVSE Settings
byte rgb_lcd = 1;
byte serial_dbg = 0;
Expand All @@ -67,7 +79,7 @@ byte stuck_relay = 1;
byte vent_ck = 1;
byte temp_ck = 1;
byte auto_start = 1;
String firmware = "-";
String firmware = "0.0.0"; // TODO: change back to "-"
String protocol = "-";

// Default OpenEVSE Fault Counters
Expand All @@ -82,9 +94,24 @@ long watthour_total = 0;
void create_rapi_json(JsonDocument &doc)
{
doc["amp"] = amp * AMPS_SCALE_FACTOR;
doc["amp/L1"] = amp_phase[0] * AMPS_SCALE_FACTOR;
doc["amp/L2"] = amp_phase[1] * AMPS_SCALE_FACTOR;
doc["amp/L3"] = amp_phase[2] * AMPS_SCALE_FACTOR;

doc["voltage"] = voltage * VOLTS_SCALE_FACTOR;
doc["voltage/L1"] = volt_phase[0] * VOLTS_SCALE_FACTOR;
doc["voltage/L2"] = volt_phase[1] * VOLTS_SCALE_FACTOR;
doc["voltage/L3"] = volt_phase[2] * VOLTS_SCALE_FACTOR;

doc["main_amp/L1"] = amp_phase_sys[0] * AMPS_SCALE_FACTOR;
doc["main_amp/L2"] = amp_phase_sys[1] * AMPS_SCALE_FACTOR;
doc["main_amp/L3"] = amp_phase_sys[2] * AMPS_SCALE_FACTOR;


doc["pilot"] = pilot;
doc["wh"] = watthour_total;
doc["wh_current"] = wattsec / 3600;
doc["elapsed"] = elapsed;
if(temp1_valid) {
doc["temp1"] = temp1 * TEMP_SCALE_FACTOR;
} else {
Expand Down Expand Up @@ -112,6 +139,7 @@ void create_rapi_json(JsonDocument &doc)
doc["state"] = state;
doc["freeram"] = ESPAL.getFreeHeap();
doc["divertmode"] = divertmode;
doc["smartevse_mode"] = smartevse_mode;
doc["srssi"] = WiFi.RSSI();
}

Expand Down Expand Up @@ -213,6 +241,48 @@ update_rapi_values() {
}
}
});
case 7:
rapiSender.sendCmd("$GX", [](int ret)
{
if(RAPI_RESPONSE_OK == ret) {
if(rapiSender.getTokenCnt() >= 2)
{
smartevse_mode = strtol(rapiSender.getToken(1), NULL, 16);
if (smartevse_mode==2) {
if (config_charge_mode()!=1 || divert_feed_type!="internal" || divertmode!=DIVERT_MODE_ECO) {
config_set("charge_mode",String("eco"));
config_set("divert_feed_type", String("internal"));
divertmode_update(DIVERT_MODE_ECO);
}
} else {
if (config_charge_mode()==1 && (!config_divert_enabled() || divert_feed_type=="internal") )
config_set("charge_mode",String("fast"));
}
}
} else {
if (config_charge_mode()==1 && (!config_divert_enabled() || divert_feed_type=="internal") )
config_set("charge_mode",String("fast"));
}
});
case 8:
rapiSender.sendCmd("$GY", [](int ret)
{
if(RAPI_RESPONSE_OK == ret) {
if(rapiSender.getTokenCnt() >= 10)
{
amp_phase_sys[0] = strtol(rapiSender.getToken(1), NULL, 10) / 1000.0;
amp_phase_sys[1] = strtol(rapiSender.getToken(2), NULL, 10) / 1000.0;
amp_phase_sys[2] = strtol(rapiSender.getToken(3), NULL, 10) / 1000.0;
amp_phase[0] = strtol(rapiSender.getToken(4), NULL, 10) / 1000.0;
amp_phase[1] = strtol(rapiSender.getToken(5), NULL, 10) / 1000.0;
amp_phase[2] = strtol(rapiSender.getToken(6), NULL, 10) / 1000.0;
volt_phase[0] = strtol(rapiSender.getToken(7), NULL, 10) / 1000.0;
volt_phase[1] = strtol(rapiSender.getToken(8), NULL, 10) / 1000.0;
volt_phase[2] = strtol(rapiSender.getToken(9), NULL, 10) / 1000.0;
}
}
});
default:
rapi_command = 0; //Last RAPI command
break;
}
Expand Down
6 changes: 6 additions & 0 deletions src/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <ArduinoJson.h>
#include "RapiSender.h"

#define SMARTEVSE_MODE_NORMAL 0
#define SMARTEVSE_MODE_SMART 1
#define SMARTEVSE_MODE_SOLAR 2

extern RapiSender rapiSender;

extern String url;
Expand All @@ -21,6 +25,8 @@ extern bool temp3_valid;
extern long pilot; // OpenEVSE Pilot Setting
extern long state; // OpenEVSE State
extern long elapsed; // Elapsed time (only valid if charging)
extern String estate; // Common name for State
extern int smartevse_mode; // SmartEVSE charge mode (NORMAL, SMART, SOLAR)

//Defaults OpenEVSE Settings
extern byte rgb_lcd;
Expand Down
Loading