Skip to content

Commit a2287a2

Browse files
committed
Merge branch 'master' of github.com:OpenEVSE/ESP32_WiFi_V3.x
2 parents feb2bfc + 67dc05c commit a2287a2

File tree

12 files changed

+1309
-1760
lines changed

12 files changed

+1309
-1760
lines changed

.github/workflows/build.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ jobs:
2727
- openevse_esp32-gateway-old
2828
- openevse_esp32-gateway-e
2929
- openevse_esp32-gateway-f
30+
- openevse_esp32-gateway-e_dev
31+
- openevse_esp32-gateway-f_dev
32+
- openevse_esp32-poe-iso
3033
- openevse_esp32-heltec-wifi-lora-v2
3134

3235
steps:

api.yml

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
openapi: 3.0.2
1+
openapi: 3.0.3
22
info:
33
title: OpenEVSE WiFi API
44
description: |
@@ -73,6 +73,42 @@ paths:
7373
offset: '+0000'
7474
tags:
7575
- Status
76+
post:
77+
operationId: postStatus
78+
summary: Update external data to EVSE status
79+
description: |
80+
The status endpoint can be called to post external data that should be updated by MQTT
81+
If MQTT is not an option, all external data needed can be updated from an HTTP POST request to /status endpoint.
82+
83+
Accepted parameters:
84+
{
85+
"voltage": int, // live voltage in V
86+
"shaper_live_pwr": int, // total household live power in W
87+
"solar": int, // divert solar production in W
88+
"grid_ie": int, // divert grid -import/+export in W
89+
"battery_level": int, // vehicle soc in %
90+
"battery_range": int, // vehicle range
91+
"time_to_full_charge" // vehicle charge ETA
92+
}
93+
94+
responses:
95+
'200':
96+
description: OK
97+
content:
98+
application/json:
99+
schema:
100+
$ref: ./models/Status.yaml
101+
examples:
102+
EVSE Status:
103+
"voltage": 220
104+
"shaper_live_pwr": 3400
105+
"solar": 3000
106+
"grid_ie": 3000
107+
"battery_level": 85
108+
"battery_range": 230
109+
"time_to_full_charge" 1590
110+
tags:
111+
- Status
76112
/ws:
77113
get:
78114
operationId: statusUpdates
@@ -87,6 +123,8 @@ paths:
87123
application/json:
88124
schema:
89125
$ref: ./models/Status.yaml
126+
'400':
127+
descritpion: Error
90128
tags:
91129
- Status
92130
/config:

docs/user-guide.md

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,32 @@
44

55
<!-- toc -->
66

7-
* [Hardware](#hardware)
8-
* [WiFi Setup](#wifi-setup)
9-
* [Charging Mode: Eco](#charging-mode--eco)
10-
* [Eco Mode Setup](#eco-mode-setup)
11-
* [Eco Mode Advanced Settings](#eco-mode-advanced-settings)
12-
* [Services](#services)
13-
* [Emoncms data logging](#emoncms-data-logging)
14-
* [MQTT](#mqtt)
15-
* [OpenEVSE Status via MQTT](#openevse-status-via-mqtt)
16-
* [OhmConnect](#ohmconnect)
17-
* [System](#system)
18-
* [Authentication](#authentication)
19-
* [WiFi Reset](#wifi-reset)
20-
* [HTTP Auth Password reset](#http-auth-password-reset)
21-
* [Hardware Factory Reset](#hardware-factory-reset)
22-
* [Firmware update](#firmware-update)
23-
* [Via Web Interface](#via-web-interface)
24-
* [Via Network OTA](#via-network-ota)
25-
* [Via USB Serial Programmer](#via-usb-serial-programmer)
7+
- [User Guide](#user-guide)
8+
- [Contents](#contents)
9+
- [Hardware](#hardware)
10+
- [WiFi Hardware](#wifi-hardware)
11+
- [Temperature sensors](#temperature-sensors)
12+
- [WiFi Setup](#wifi-setup)
13+
- [Charging Mode: Eco](#charging-mode-eco)
14+
- [Eco Mode Setup](#eco-mode-setup)
15+
- [using MQTT](#using-mqtt)
16+
- [using HTTP](#using-http)
17+
- [Eco Mode Advanced Settings](#eco-mode-advanced-settings)
18+
- [Services](#services)
19+
- [Emoncms data logging](#emoncms-data-logging)
20+
- [Current Shaper](#current-shaper)
21+
- [External values settable from HTTP POST](#external-values-settable-from-http-post)
22+
- [MQTT](#mqtt)
23+
- [OhmConnect](#ohmconnect)
24+
- [System](#system)
25+
- [Authentication](#authentication)
26+
- [WiFi Reset](#wifi-reset)
27+
- [HTTP Auth Password reset](#http-auth-password-reset)
28+
- [Hardware Factory Reset](#hardware-factory-reset)
29+
- [Firmware update](#firmware-update)
30+
- [Via Web Interface](#via-web-interface)
31+
- [Via Network OTA](#via-network-ota)
32+
- [Via USB Serial Programmer](#via-usb-serial-programmer)
2633

2734
<!-- tocstop -->
2835

@@ -72,7 +79,8 @@ On first boot, OpenEVSE should broadcast a WiFi access point (AP) `OpenEVSE_XXXX
7279

7380
## Charging Mode: Eco
7481

75-
'Eco' charge mode allows the OpenEVSE to start/stop and adjust the charging current automatically based on an MQTT. This feed could be the amount of solar PV generation or the amount of excess power (grid export). 'Normal' charge mode charges the EV at the maximum rate set.
82+
'Eco' charge mode allows the OpenEVSE to start/stop and adjust the charging current automatically based on an MQTT feed or received by HTTP POST request ( see below ). This feed could be the amount of solar PV generation or the amount of excess power (grid export). 'Normal' charge mode charges the EV at the maximum rate set.
83+
7684

7785
![eco](eco.png)
7886

@@ -88,15 +96,20 @@ A [OpenEnergyMonitor Solar PV Energy Monitor](https://guide.openenergymonitor.or
8896

8997
### Eco Mode Setup
9098

99+
#### using MQTT
91100
* Enable MQTT Service
92101
* [emonPi MQTT credentials](https://guide.openenergymonitor.org/technical/credentials/#mqtt) should be pre-populated
93102
* Enter solar PV generation or Grid (+I/-E) MQTT topic e.g. Assuming [standard emonPi Solar PV setup](https://guide.openenergymonitor.org/applications/solar-pv/), the default MQTT feeds are:
94103
* Grid Import (positive Import / Negative export*): `emon/emonpi/power1`
95104
* Solar PV generation (always postive): `emon/emonpi/power2`
96105

106+
#### using HTTP
107+
* send HTTP POST to http://{openevse_host}/status containing JSON formatted as /status GET endpoint
108+
* body can contain {"solar": value} or {"grid_ie": value} in watt.
109+
97110
> **Note #1**: 'Grid' feed should include the power consumed by the EVSE
98111
>
99-
> **Note #2**: The EVSE expects the MQTT data to update every 5-10s, perforamce will be degraded if the update interval is much faster or slower than this
112+
> **Note #2**: The EVSE expects the MQTT/HTTP data to update every 5-10s, perforamce will be degraded if the update interval is much faster or slower than this
100113
101114
CT sensor can be physically reversed on the cable to invert the reading.
102115

@@ -138,11 +151,32 @@ Data can be posted using HTTP or HTTPS.
138151

139152
OpenEVSE can shape charge current according to your real time house load, preventing to exceed the maximum power your energy plan can handle.
140153
Once the module is toggled on, it will have highest priority to other claims.
141-
However it's possible to temporary disable it if needed with HTTP or MQTT
142-
143-
**Note #1**: this service is dependant to MQTT, it needs a topic with the whole household live power in watts ( 'Live power load MQTT Topic' )
154+
However it's possible to temporary disable it if needed with HTTP or MQTT. For HTTP, send a text/plain HTTP POST request to /shaper with body containing shaper=value
155+
156+
**Note #1**: this service is dependant of an external feed containing the household live power in watt.
157+
It can come from an MQTT topic or an HTTP POST request.
158+
*** MQTT ***
159+
Set the topic in the shaper configuration page ( 'Live power load MQTT Topic' )
160+
*** HTTP ***
161+
Send periodically an HTTP POST request to http://{openevse_host}/status containing TEXT formatted like in /status GET endpoint.
162+
Body should contain {"shaper_live_pwr": value} in watt. Can be combined with other settable values.
163+
144164
**Note #2**: set 'Max Power Allowed' according to your energy plan.
145165

166+
### External values settable from HTTP POST
167+
168+
If MQTT is not an option, all external data needed can be updated from an HTTP POST request to /status endpoint.
169+
170+
Accepted data:
171+
{
172+
"voltage": int, // live voltage in V
173+
"shaper_live_pwr": int, // total household live power in W
174+
"solar": int, // divert solar production in W
175+
"grid_ie": int, // divert grid -import/+export in W
176+
"battery_level": int, // vehicle soc in %
177+
"battery_range": int, // vehicle range
178+
"time_to_full_charge" // vehicle charge ETA
179+
}
146180

147181
### MQTT
148182

platformio.ini

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -249,28 +249,6 @@ build_flags =
249249
-D RANDOM_SEED_CHANNEL=1
250250
# https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/ETH_LAN8720/ETH_LAN8720.ino
251251

252-
[env:openevse_esp32-gateway-e]
253-
# For hardware RevE
254-
# https://github.com/OpenEVSE/ESP32_WiFi_V3.x/blob/master/docs/wired-ethernet.md
255-
board = esp32-gateway
256-
build_flags =
257-
${common.build_flags}
258-
${common.version}
259-
${common.src_build_flags}
260-
-D WIFI_LED=33
261-
-D WIFI_LED_ON_STATE=HIGH
262-
-D WIFI_BUTTON=34
263-
-D WIFI_BUTTON_PRESSED_STATE=LOW
264-
-D DEBUG_PORT=Serial
265-
-D RAPI_PORT=Serial2
266-
-D ENABLE_WIRED_ETHERNET
267-
-D RANDOM_SEED_CHANNEL=1
268-
-D RX2=16
269-
-D TX2=32
270-
-D RESET_ETH_PHY_ON_BOOT=1
271-
board_build.extra_flags = "-DARDUINO_ESP32_GATEWAY=\'E\'"
272-
upload_speed = 921600
273-
274252
[env:openevse_esp32-gateway-f]
275253
# For hardware RevF and RevG
276254
# https://github.com/OpenEVSE/ESP32_WiFi_V3.x/blob/master/docs/wired-ethernet.md
@@ -292,9 +270,33 @@ build_flags =
292270
board_build.extra_flags = "-DARDUINO_ESP32_GATEWAY=\'F\'"
293271
upload_speed = 921600
294272

273+
[env:openevse_esp32-gateway-e]
274+
# For hardware RevE
275+
# https://github.com/OpenEVSE/ESP32_WiFi_V3.x/blob/master/docs/wired-ethernet.md
276+
extends = env:openevse_esp32-gateway-f
277+
build_flags =
278+
${env:openevse_esp32-gateway-f.build_flags}
279+
-D RESET_ETH_PHY_ON_BOOT=1
280+
board_build.extra_flags = "-DARDUINO_ESP32_GATEWAY=\'E\'"
281+
282+
[env:openevse_esp32-gateway-e_dev]
283+
extends = env:openevse_esp32-gateway-e
284+
build_flags =
285+
${env:openevse_esp32-gateway-e.build_flags}
286+
${common.debug_flags}
287+
build_type = debug
288+
board_build.partitions = ${common.build_partitions_debug}
289+
290+
[env:openevse_esp32-gateway-f_dev]
291+
extends = env:openevse_esp32-gateway-f
292+
build_flags =
293+
${env:openevse_esp32-gateway-f.build_flags}
294+
${common.debug_flags}
295+
build_type = debug
296+
board_build.partitions = ${common.build_partitions_debug}
297+
295298
[env:openevse_esp32-poe-iso]
296299
# Tested against Rev C board
297-
extends = env:openevse_esp32-gateway
298300
board = esp32-poe-iso
299301
build_flags =
300302
${common.build_flags}
@@ -309,14 +311,6 @@ build_flags =
309311
-D RESET_ETH_PHY_ON_BOOT=1
310312
upload_speed = 921600
311313

312-
[env:openevse_esp32-gateway-e_dev]
313-
extends = env:openevse_esp32-gateway-e
314-
build_flags =
315-
${env:openevse_esp32-gateway-e.build_flags}
316-
${common.debug_flags}
317-
build_type = debug
318-
board_build.partitions = ${common.build_partitions_debug}
319-
320314
[env:openevse_esp32-heltec-wifi-lora-v2]
321315
board = heltec_wifi_lora_32_V2
322316
build_flags =

src/current_shaper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void CurrentShaperTask::notifyConfigChanged( bool enabled, uint32_t max_pwr) {
7676
_max_pwr = max_pwr;
7777
if (!enabled) evse.release(EvseClient_OpenEVSE_Shaper);
7878
StaticJsonDocument<128> event;
79-
event["shaper"] = enabled;
79+
event["shaper"] = enabled == true ? 1 : 0;
8080
event["shaper_max_pwr"] = max_pwr;
8181
event_send(event);
8282
}

src/mqtt.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ void mqttmsg_callback(MongooseString topic, MongooseString payload) {
125125
{
126126
byte newshaper = payload_str.toInt();
127127
if (newshaper==0) {
128-
shaper.setState(0);
128+
shaper.setState(false);
129129
} else if (newshaper==1) {
130-
shaper.setState(1);
130+
shaper.setState(true);
131131
}
132132
}
133133
// Manual Override

src/web_server.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ void buildStatus(DynamicJsonDocument &doc) {
241241
doc["divert_update"] = (millis() - divert.getLastUpdate()) / 1000;
242242
doc["divert_active"] = divert.isActive();
243243

244-
doc["shaper"] = shaper.isActive();
244+
doc["shaper"] = shaper.isActive()?1:0;
245245
doc["shaper_live_pwr"] = shaper.getLivePwr();
246246
doc["shaper_chg_cur"] = shaper.getChgCur();
247247

@@ -683,6 +683,8 @@ void handleStatusPost(MongooseHttpServerRequest *request, MongooseHttpServerResp
683683
DeserializationError error = deserializeJson(doc, body);
684684
if(!error)
685685
{
686+
bool send_event = true;
687+
686688
if(doc.containsKey("voltage"))
687689
{
688690
double volts = doc["voltage"];
@@ -699,29 +701,36 @@ void handleStatusPost(MongooseHttpServerRequest *request, MongooseHttpServerResp
699701
solar = doc["solar"];
700702
DBUGF("solar:%dW", solar);
701703
divert.update_state();
704+
send_event = false; // Divert sends the event so no need to send here
702705
}
703706
else if(doc.containsKey("grid_ie")) {
704707
grid_ie = doc["grid_ie"];
705708
DBUGF("grid:%dW", grid_ie);
706709
divert.update_state();
710+
send_event = false; // Divert sends the event so no need to send here
707711
}
708712
if(doc.containsKey("battery_level")) {
709713
double vehicle_soc = doc["battery_level"];
710714
DBUGF("vehicle_soc:%d%%", vehicle_soc);
711715
evse.setVehicleStateOfCharge(vehicle_soc);
716+
doc["vehicle_state_update"] = 0;
712717
}
713718
if(doc.containsKey("battery_range")) {
714719
double vehicle_range = doc["battery_range"];
715720
DBUGF("vehicle_range:%dKM", vehicle_range);
716721
evse.setVehicleRange(vehicle_range);
722+
doc["vehicle_state_update"] = 0;
717723
}
718724
if(doc.containsKey("time_to_full_charge")){
719725
double vehicle_eta = doc["time_to_full_charge"];
720726
DBUGF("vehicle_eta:%d", vehicle_eta);
721-
evse.setVehicleEta(vehicle_eta);
727+
evse.setVehicleEta(vehicle_eta);
728+
doc["vehicle_state_update"] = 0;
722729
}
723730
// send back new value to clients
724-
event_send(doc);
731+
if(send_event) {
732+
event_send(doc);
733+
}
725734

726735
response->setCode(200);
727736
serializeJson(doc, *response);
@@ -733,7 +742,7 @@ void handleStatusPost(MongooseHttpServerRequest *request, MongooseHttpServerResp
733742

734743

735744
void
736-
handleStatus(MongooseHttpServerRequest *request)
745+
handleStatus(MongooseHttpServerRequest *request)
737746
{
738747

739748
MongooseHttpServerResponseStream *response;

src/web_server_events.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void handleEventLogs(MongooseHttpServerRequest *request)
6363
event["temperature"] = temperature;
6464
event["temperatureMax"] = temperatureMax;
6565
event["divertMode"] = divertMode;
66-
event["shaper"] = shaper;
66+
event["shaper"] = shaper == true?1:0;
6767
serializeJson(event, *response);
6868
});
6969

0 commit comments

Comments
 (0)