Skip to content

Commit 213a26f

Browse files
basmeermanclaude
andcommitted
feat: add evse_charging_enabled() helper with tests for EVCC integration
Extract the charging_enabled derivation into a testable pure C function in http_api.c. Add 3 tests covering STATE_C, STATE_C1, and all non-charging states. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 309bd57 commit 213a26f

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

SmartEVSE-3/src/http_api.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ char evse_state_to_iec61851(int state, int error_flags) {
5353
}
5454
}
5555

56+
bool evse_charging_enabled(int state) {
57+
return (state == STATE_C || state == STATE_C1);
58+
}
59+
5660
const char *http_api_validate_phase_switch(const http_phase_switch_request_t *req,
5761
int enable_c2, int load_bl) {
5862
if (req->phases != 1 && req->phases != 3)

SmartEVSE-3/src/http_api.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ const char *http_api_validate_phase_switch(const http_phase_switch_request_t *re
104104
// NOSTATE or unrecognized values return 'F' (not available).
105105
char evse_state_to_iec61851(int state, int error_flags);
106106

107+
// Derive whether charging is actively enabled from internal state.
108+
// Returns true when the EVSE is delivering energy (STATE_C or STATE_C1).
109+
bool evse_charging_enabled(int state);
110+
107111
#ifdef __cplusplus
108112
}
109113
#endif

SmartEVSE-3/src/http_handlers.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ bool handle_URI(struct mg_connection *c, struct mg_http_message *hm, webServerR
170170
doc["evse"]["rfid"] = !RFIDReader ? "Not Installed" : RFIDstatus >= 8 ? "NOSTATUS" : StrRFIDStatusWeb[RFIDstatus];
171171
char iec_buf[2] = {evse_state_to_iec61851(State, ErrorFlags), '\0'};
172172
doc["evse"]["iec61851_state"] = iec_buf;
173-
doc["evse"]["charging_enabled"] = (State == STATE_C || State == STATE_C1);
173+
doc["evse"]["charging_enabled"] = evse_charging_enabled(State);
174174
if (RFIDReader) {
175175
char buf[15];
176176
printRFID(buf, sizeof(buf));

SmartEVSE-3/test/native/tests/test_http_api.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,52 @@ void test_iec61851_nostate_and_unknown(void) {
787787
TEST_ASSERT_EQUAL_INT('F', evse_state_to_iec61851(99, NO_ERROR));
788788
}
789789

790+
// ---- Charging Enabled Derivation ----
791+
792+
/*
793+
* @feature EVCC Charging Enabled
794+
* @req REQ-API-025
795+
* @scenario STATE_C means charging is enabled
796+
* @given The EVSE is in STATE_C (charging)
797+
* @when evse_charging_enabled is called
798+
* @then It returns true
799+
*/
800+
void test_charging_enabled_state_c(void) {
801+
TEST_ASSERT_TRUE(evse_charging_enabled(STATE_C));
802+
}
803+
804+
/*
805+
* @feature EVCC Charging Enabled
806+
* @req REQ-API-025
807+
* @scenario STATE_C1 means charging is enabled (stopping phase)
808+
* @given The EVSE is in STATE_C1 (charge stopping)
809+
* @when evse_charging_enabled is called
810+
* @then It returns true because energy is still being delivered
811+
*/
812+
void test_charging_enabled_state_c1(void) {
813+
TEST_ASSERT_TRUE(evse_charging_enabled(STATE_C1));
814+
}
815+
816+
/*
817+
* @feature EVCC Charging Enabled
818+
* @req REQ-API-025
819+
* @scenario Non-charging states return false
820+
* @given The EVSE is in STATE_A, STATE_B, or other non-charging states
821+
* @when evse_charging_enabled is called
822+
* @then It returns false
823+
*/
824+
void test_charging_enabled_non_charging_states(void) {
825+
TEST_ASSERT_FALSE(evse_charging_enabled(STATE_A));
826+
TEST_ASSERT_FALSE(evse_charging_enabled(STATE_B));
827+
TEST_ASSERT_FALSE(evse_charging_enabled(STATE_B1));
828+
TEST_ASSERT_FALSE(evse_charging_enabled(STATE_D));
829+
TEST_ASSERT_FALSE(evse_charging_enabled(STATE_COMM_B));
830+
TEST_ASSERT_FALSE(evse_charging_enabled(STATE_ACTSTART));
831+
TEST_ASSERT_FALSE(evse_charging_enabled(STATE_MODEM_REQUEST));
832+
TEST_ASSERT_FALSE(evse_charging_enabled(STATE_MODEM_DENIED));
833+
TEST_ASSERT_FALSE(evse_charging_enabled(NOSTATE));
834+
}
835+
790836
// ---- Phase Switch Validation ----
791837

792838
/*
@@ -976,6 +1022,11 @@ int main(void) {
9761022
RUN_TEST(test_iec61851_soft_errors_no_override);
9771023
RUN_TEST(test_iec61851_nostate_and_unknown);
9781024

1025+
// Charging enabled derivation
1026+
RUN_TEST(test_charging_enabled_state_c);
1027+
RUN_TEST(test_charging_enabled_state_c1);
1028+
RUN_TEST(test_charging_enabled_non_charging_states);
1029+
9791030
// Phase switch validation
9801031
RUN_TEST(test_phase_switch_valid_1p);
9811032
RUN_TEST(test_phase_switch_valid_3p);

0 commit comments

Comments
 (0)