Skip to content

Commit 796e142

Browse files
Merge pull request #213 from OpenEVSE/jeremypoulter/issue192
Fix for operation with both timer and PV Divert active
2 parents f4e2546 + 36e5c19 commit 796e142

File tree

10 files changed

+272
-31
lines changed

10 files changed

+272
-31
lines changed

src/divert.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void divertmode_update(byte newmode)
9292
event["smoothed_available_current"] = smoothed_available_current = 0;
9393

9494
EvseProperties props(EvseState::Disabled);
95-
evse.claim(EvseClient_OpenEVSE_Divert, EvseManager_Priority_Divert, props);
95+
evse.claim(EvseClient_OpenEVSE_Divert, EvseManager_Priority_Default, props);
9696
} break;
9797

9898
default:
@@ -208,7 +208,7 @@ void divert_update_state()
208208
if(divert_active && divertmode_get_time() >= min_charge_end)
209209
{
210210
EvseProperties props(EvseState::Disabled);
211-
evse.claim(EvseClient_OpenEVSE_Divert, EvseManager_Priority_Divert, props);
211+
evse.claim(EvseClient_OpenEVSE_Divert, EvseManager_Priority_Default, props);
212212

213213
if(previousState != evse.getState())
214214
{

src/evse_man.cpp

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,19 @@ EvseManager::Claim::Claim() :
109109
{
110110
}
111111

112-
void EvseManager::Claim::claim(EvseClient client, int priority, EvseProperties &target)
112+
bool EvseManager::Claim::claim(EvseClient client, int priority, EvseProperties &target)
113113
{
114-
_client = client;
115-
_priority = priority;
116-
_properties = target;
114+
if(_client != client ||
115+
_priority != priority ||
116+
_properties != target)
117+
{
118+
_client = client;
119+
_priority = priority;
120+
_properties = target;
121+
return true;
122+
}
123+
124+
return false;
117125
}
118126

119127
void EvseManager::Claim::release()
@@ -385,7 +393,7 @@ bool EvseManager::claim(EvseClient client, int priority, EvseProperties &target)
385393
{
386394
Claim *slot = NULL;
387395

388-
DBUGF("New claim from 0x%08x, priority %d, %s", client, priority, target.getState().toString());
396+
DBUGF("Claim from 0x%08x, priority %d, %s", client, priority, target.getState().toString());
389397

390398
for (size_t i = 0; i < EVSE_MANAGER_MAX_CLIENT_CLAIMS; i++)
391399
{
@@ -400,10 +408,13 @@ bool EvseManager::claim(EvseClient client, int priority, EvseProperties &target)
400408

401409
if(slot)
402410
{
403-
DBUGF("Found slot, waking task");
404-
slot->claim(client, priority, target);
405-
_evaluateClaims = true;
406-
MicroTask.wakeTask(this);
411+
DBUGF("Found slot");
412+
if(slot->claim(client, priority, target))
413+
{
414+
DBUGF("Claim added/updated, waking task");
415+
_evaluateClaims = true;
416+
MicroTask.wakeTask(this);
417+
}
407418
return true;
408419
}
409420

@@ -524,3 +535,41 @@ uint32_t EvseManager::getTimeLimit(EvseClient client)
524535
{
525536
return getClaimProperties(client).getTimeLimit();
526537
}
538+
539+
bool EvseManager::isRapiCommandBlocked(String rapi)
540+
{
541+
return rapi.startsWith("$ST");
542+
}
543+
544+
bool EvseManager::serializeClaims(DynamicJsonDocument &doc)
545+
{
546+
doc.to<JsonArray>();
547+
548+
for(size_t i = 0; i < EVSE_MANAGER_MAX_CLIENT_CLAIMS; i++)
549+
{
550+
Claim &claim = _clients[i];
551+
if(claim.isValid())
552+
{
553+
JsonObject obj = doc.createNestedObject();
554+
obj["client"] = claim.getClient();
555+
obj["priority"] = claim.getPriority();
556+
claim.getProperties().serialize(obj);
557+
}
558+
}
559+
560+
return true;
561+
}
562+
563+
bool EvseManager::serializeClaim(DynamicJsonDocument &doc, EvseClient client)
564+
{
565+
Claim *claim;
566+
567+
if(findClaim(client, &claim))
568+
{
569+
doc["priority"] = claim->getPriority();
570+
claim->getProperties().serialize(doc);
571+
return true;
572+
}
573+
574+
return false;
575+
}

src/evse_man.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ typedef uint32_t EvseClient;
3939
#define EvseManager_Priority_Divert 50
4040
#define EvseManager_Priority_Timer 100
4141
#define EvseManager_Priority_Boost 200
42+
#define EvseManager_Priority_API 500
4243
#define EvseManager_Priority_Ohm 500
4344
#define EvseManager_Priority_Manual 1000
4445
#define EvseManager_Priority_Ocpp 1050
@@ -163,6 +164,34 @@ class EvseProperties : virtual public JsonSerialize<512>
163164
return *this;
164165
}
165166

167+
bool equals(EvseProperties &rhs) {
168+
return this->_state == rhs._state &&
169+
this->_charge_current == rhs._charge_current &&
170+
this->_max_current == rhs._max_current &&
171+
this->_energy_limit == rhs._energy_limit &&
172+
this->_time_limit == rhs._time_limit &&
173+
this->_auto_release == rhs._auto_release;
174+
175+
}
176+
bool equals(EvseState &rhs) {
177+
return this->_state == rhs;
178+
}
179+
180+
bool operator == (EvseProperties &rhs) {
181+
return this->equals(rhs);
182+
}
183+
bool operator == (EvseState &rhs) {
184+
return this->equals(rhs);
185+
}
186+
187+
bool operator != (EvseProperties &rhs) {
188+
return !equals(rhs);
189+
}
190+
bool operator != (EvseState &rhs) {
191+
return !equals(rhs);
192+
}
193+
194+
166195
using JsonSerialize::deserialize;
167196
virtual bool deserialize(JsonObject &obj);
168197
using JsonSerialize::serialize;
@@ -182,7 +211,7 @@ class EvseManager : public MicroTasks::Task
182211
public:
183212
Claim();
184213

185-
void claim(EvseClient client, int priority, EvseProperties &target);
214+
bool claim(EvseClient client, int priority, EvseProperties &target);
186215
void release();
187216

188217
bool isValid() {
@@ -279,6 +308,9 @@ class EvseManager : public MicroTasks::Task
279308
uint32_t getEnergyLimit(EvseClient client = EvseClient_NULL);
280309
uint32_t getTimeLimit(EvseClient client = EvseClient_NULL);
281310

311+
bool serializeClaims(DynamicJsonDocument &doc);
312+
bool serializeClaim(DynamicJsonDocument &doc, EvseClient client);
313+
282314
// Evse Status
283315
bool isConnected() {
284316
return OpenEVSE.isConnected();
@@ -398,6 +430,8 @@ class EvseManager : public MicroTasks::Task
398430
void onSessionComplete(MicroTasks::EventListener *listner) {
399431
_monitor.onSessionComplete(listner);
400432
}
433+
434+
bool isRapiCommandBlocked(String rapi);
401435
};
402436

403437
#endif // !_OPENEVSE_EVSE_MAN_H

src/main.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,8 @@ loop() {
198198
// -------------------------------------------------------------------
199199
// Do these things once every 30 seconds
200200
// -------------------------------------------------------------------
201-
if ((millis() - Timer1) >= 30000) {
202-
DBUGLN("Time1");
203-
201+
if ((millis() - Timer1) >= 30000)
202+
{
204203
if(!Update.isRunning())
205204
{
206205
if(config_ohm_enabled()) {

src/mqtt.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,19 @@ void mqttmsg_callback(MongooseString topic, MongooseString payload) {
9595
cmd += " "+payload_str;
9696
}
9797

98-
rapiSender.sendCmd(cmd, [](int ret)
98+
if(!evse.isRapiCommandBlocked(cmd))
9999
{
100-
if (RAPI_RESPONSE_OK == ret || RAPI_RESPONSE_NK == ret)
100+
rapiSender.sendCmd(cmd, [](int ret)
101101
{
102-
String rapiString = rapiSender.getResponse();
103-
String mqtt_data = rapiString;
104-
String mqtt_sub_topic = mqtt_topic + "/rapi/out";
105-
mqttclient.publish(mqtt_sub_topic, mqtt_data);
106-
}
107-
});
102+
if (RAPI_RESPONSE_OK == ret || RAPI_RESPONSE_NK == ret)
103+
{
104+
String rapiString = rapiSender.getResponse();
105+
String mqtt_data = rapiString;
106+
String mqtt_sub_topic = mqtt_topic + "/rapi/out";
107+
mqttclient.publish(mqtt_sub_topic, mqtt_data);
108+
}
109+
});
110+
}
108111
}
109112
}
110113
} //end call back

src/scheduler.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ unsigned long Scheduler::loop(MicroTasks::WakeReason reason)
204204
DBUGF("Starting %s claim",
205205
currentEvent.getState().toString());
206206
EvseProperties properties(currentEvent.getState());
207-
_evse->claim(EvseClient_OpenEVSE_Schedule, EvseManager_Priority_Timer, properties);
207+
_evse->claim(EvseClient_OpenEVSE_Schedule,
208+
EvseState::Active == currentEvent.getState() ? EvseManager_Priority_Timer : EvseManager_Priority_Default,
209+
properties);
208210
} else {
209211
// No scheduled events, release any claims
210212
DBUGLN("releasing claims");

src/web_server.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ const char _CONTENT_TYPE_JPEG[] PROGMEM = "image/jpeg";
5858
const char _CONTENT_TYPE_PNG[] PROGMEM = "image/png";
5959
const char _CONTENT_TYPE_SVG[] PROGMEM = "image/svg+xml";
6060

61+
#define RAPI_RESPONSE_BLOCKED -300
62+
63+
void handleEvseClaims(MongooseHttpServerRequest *request);
64+
6165
void dumpRequest(MongooseHttpServerRequest *request)
6266
{
6367
#ifdef ENABLE_DEBUG_WEB_REQUEST
@@ -119,7 +123,7 @@ void dumpRequest(MongooseHttpServerRequest *request)
119123
// -------------------------------------------------------------------
120124
// Helper function to perform the standard operations on a request
121125
// -------------------------------------------------------------------
122-
bool requestPreProcess(MongooseHttpServerRequest *request, MongooseHttpServerResponseStream *&response, fstr_t contentType = CONTENT_TYPE_JSON)
126+
bool requestPreProcess(MongooseHttpServerRequest *request, MongooseHttpServerResponseStream *&response, fstr_t contentType)
123127
{
124128
dumpRequest(request);
125129

@@ -587,6 +591,8 @@ handleStatus(MongooseHttpServerRequest *request) {
587591

588592
create_rapi_json(doc);
589593

594+
doc["status"] = evse.getState().toString();
595+
590596
doc["elapsed"] = evse.getSessionElapsed();
591597
doc["wattsec"] = evse.getSessionEnergy() * SESSION_ENERGY_SCALE_FACTOR;
592598
doc["watthour"] = evse.getTotalEnergy() * TOTAL_ENERGY_SCALE_FACTOR;
@@ -1097,12 +1103,18 @@ handleRapi(MongooseHttpServerRequest *request) {
10971103
if (request->hasParam("rapi"))
10981104
{
10991105
String rapi = request->getParam("rapi");
1106+
int ret = RAPI_RESPONSE_NK;
11001107

1101-
// BUG: Really we should do this in the main loop not here...
1102-
RAPI_PORT.flush();
1103-
DBUGVAR(rapi);
1104-
int ret = rapiSender.sendCmdSync(rapi);
1105-
DBUGVAR(ret);
1108+
if(!evse.isRapiCommandBlocked(rapi))
1109+
{
1110+
// BUG: Really we should do this in the main loop not here...
1111+
RAPI_PORT.flush();
1112+
DBUGVAR(rapi);
1113+
ret = rapiSender.sendCmdSync(rapi);
1114+
DBUGVAR(ret);
1115+
} else {
1116+
ret = RAPI_RESPONSE_BLOCKED;
1117+
}
11061118

11071119
if(RAPI_RESPONSE_OK == ret ||
11081120
RAPI_RESPONSE_NK == ret)
@@ -1158,6 +1170,7 @@ handleRapi(MongooseHttpServerRequest *request) {
11581170
RAPI_RESPONSE_BAD_CHECKSUM == ret ? F("RAPI_RESPONSE_BAD_CHECKSUM") :
11591171
RAPI_RESPONSE_BAD_SEQUENCE_ID == ret ? F("RAPI_RESPONSE_BAD_SEQUENCE_ID") :
11601172
RAPI_RESPONSE_ASYNC_EVENT == ret ? F("RAPI_RESPONSE_ASYNC_EVENT") :
1173+
RAPI_RESPONSE_BLOCKED == ret ? F("RAPI_RESPONSE_BLOCKED") :
11611174
F("UNKNOWN");
11621175

11631176
if (json) {
@@ -1168,7 +1181,7 @@ handleRapi(MongooseHttpServerRequest *request) {
11681181
s += errorString;
11691182
}
11701183

1171-
code = 500;
1184+
code = RAPI_RESPONSE_BLOCKED == ret ? 400 : 500;
11721185
}
11731186
}
11741187
if (false == json) {
@@ -1251,6 +1264,8 @@ web_server_setup() {
12511264
server.on("/schedule/plan$", handleSchedulePlan);
12521265
server.on("/schedule", handleSchedule);
12531266

1267+
server.on("/claims", handleEvseClaims);
1268+
12541269
server.on("/override$", handleOverride);
12551270

12561271
// Simple Firmware Update Form

src/web_server.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ extern void web_server_loop();
3636

3737
extern void web_server_event(JsonDocument &event);
3838

39+
typedef const __FlashStringHelper *fstr_t;
40+
41+
bool requestPreProcess(MongooseHttpServerRequest *request, MongooseHttpServerResponseStream *&response, fstr_t contentType = CONTENT_TYPE_JSON);
3942
void dumpRequest(MongooseHttpServerRequest *request);
4043

4144
#endif // _EMONESP_WEB_SERVER_H

0 commit comments

Comments
 (0)