From b27105394d2956807bfb0e45683b37291b6958b9 Mon Sep 17 00:00:00 2001 From: matth-x <63792403+matth-x@users.noreply.github.com> Date: Sat, 8 Jun 2024 16:21:27 +0200 Subject: [PATCH 1/3] add build flag MO_ENABLE_CONNECTOR_LOCK --- src/MicroOcpp.cpp | 2 + src/MicroOcpp.h | 4 +- .../Model/ConnectorBase/Connector.cpp | 11 +++- src/MicroOcpp/Model/ConnectorBase/Connector.h | 4 ++ .../ConnectorBase/UnlockConnectorResult.h | 8 +++ src/MicroOcpp/Operations/UnlockConnector.cpp | 54 +++++++++++-------- src/MicroOcpp/Operations/UnlockConnector.h | 3 ++ src/MicroOcpp_c.cpp | 5 ++ src/MicroOcpp_c.h | 5 ++ tests/Api.cpp | 9 ++++ tests/ChargingSessions.cpp | 8 +++ 11 files changed, 89 insertions(+), 24 deletions(-) diff --git a/src/MicroOcpp.cpp b/src/MicroOcpp.cpp index 83451b5a..49383124 100644 --- a/src/MicroOcpp.cpp +++ b/src/MicroOcpp.cpp @@ -874,6 +874,7 @@ void setTxNotificationOutput(std::functionsetTxNotificationOutput(notificationOutput); } +#if MO_ENABLE_CONNECTOR_LOCK void setOnUnlockConnectorInOut(std::function onUnlockConnectorInOut, unsigned int connectorId) { if (!context) { MO_DBG_ERR("OCPP uninitialized"); //need to call mocpp_initialize before @@ -886,6 +887,7 @@ void setOnUnlockConnectorInOut(std::function onUnlockCo } connector->setOnUnlockConnector(onUnlockConnectorInOut); } +#endif //MO_ENABLE_CONNECTOR_LOCK bool isOperative(unsigned int connectorId) { if (!context) { diff --git a/src/MicroOcpp.h b/src/MicroOcpp.h index 93a991be..0567ea15 100644 --- a/src/MicroOcpp.h +++ b/src/MicroOcpp.h @@ -309,15 +309,17 @@ void setStopTxReadyInput(std::function stopTxReady, unsigned int connect void setTxNotificationOutput(std::function notificationOutput, unsigned int connectorId = 1); //called when transaction state changes (see TxNotification for possible events). Transaction can be null +#if MO_ENABLE_CONNECTOR_LOCK /* * Set an InputOutput (reads and sets information at the same time) for forcing to unlock the * connector. Called as part of the OCPP operation "UnlockConnector" * Return values: - * - UnlockConnectorResult_Pending if action needs more time to complete (MO will call this cb again later or eventually timeout) + * - UnlockConnectorResult_Pending if action needs more time to complete (MO will call this cb again later or eventually time out) * - UnlockConnectorResult_Unlocked if successful * - UnlockConnectorResult_UnlockFailed if not successful (e.g. lock stuck) */ void setOnUnlockConnectorInOut(std::function onUnlockConnectorInOut, unsigned int connectorId = 1); +#endif //MO_ENABLE_CONNECTOR_LOCK /* * Access further information about the internal state of the library diff --git a/src/MicroOcpp/Model/ConnectorBase/Connector.cpp b/src/MicroOcpp/Model/ConnectorBase/Connector.cpp index 1fe3d077..d284b8dd 100644 --- a/src/MicroOcpp/Model/ConnectorBase/Connector.cpp +++ b/src/MicroOcpp/Model/ConnectorBase/Connector.cpp @@ -38,12 +38,17 @@ Connector::Connector(Context& context, int connectorId) snprintf(availabilityBoolKey, sizeof(availabilityBoolKey), MO_CONFIG_EXT_PREFIX "AVAIL_CONN_%d", connectorId); availabilityBool = declareConfiguration(availabilityBoolKey, true, MO_KEYVALUE_FN, false, false, false); - + +#if MO_ENABLE_CONNECTOR_LOCK + declareConfiguration("UnlockConnectorOnEVSideDisconnect", true); //read-write +#else + declareConfiguration("UnlockConnectorOnEVSideDisconnect", false, CONFIGURATION_VOLATILE, true); //read-only because there is no connector lock +#endif //MO_ENABLE_CONNECTOR_LOCK + connectionTimeOutInt = declareConfiguration("ConnectionTimeOut", 30); minimumStatusDurationInt = declareConfiguration("MinimumStatusDuration", 0); stopTransactionOnInvalidIdBool = declareConfiguration("StopTransactionOnInvalidId", true); stopTransactionOnEVSideDisconnectBool = declareConfiguration("StopTransactionOnEVSideDisconnect", true); - declareConfiguration("UnlockConnectorOnEVSideDisconnect", true, CONFIGURATION_VOLATILE, true); localPreAuthorizeBool = declareConfiguration("LocalPreAuthorize", false); localAuthorizeOfflineBool = declareConfiguration("LocalAuthorizeOffline", true); allowOfflineTxForUnknownIdBool = MicroOcpp::declareConfiguration("AllowOfflineTxForUnknownId", false); @@ -945,6 +950,7 @@ void Connector::addErrorDataInput(std::function errorDataInput) { this->trackErrorDataInputs.push_back(false); } +#if MO_ENABLE_CONNECTOR_LOCK void Connector::setOnUnlockConnector(std::function unlockConnector) { this->onUnlockConnector = unlockConnector; } @@ -952,6 +958,7 @@ void Connector::setOnUnlockConnector(std::function unlo std::function Connector::getOnUnlockConnector() { return this->onUnlockConnector; } +#endif //MO_ENABLE_CONNECTOR_LOCK void Connector::setStartTxReadyInput(std::function startTxReady) { this->startTxReadyInput = startTxReady; diff --git a/src/MicroOcpp/Model/ConnectorBase/Connector.h b/src/MicroOcpp/Model/ConnectorBase/Connector.h index fe2cfcf2..7da8c4d4 100644 --- a/src/MicroOcpp/Model/ConnectorBase/Connector.h +++ b/src/MicroOcpp/Model/ConnectorBase/Connector.h @@ -49,7 +49,9 @@ class Connector { ChargePointStatus reportedStatus = ChargePointStatus_UNDEFINED; unsigned long t_statusTransition = 0; +#if MO_ENABLE_CONNECTOR_LOCK std::function onUnlockConnector; +#endif //MO_ENABLE_CONNECTOR_LOCK std::function startTxReadyInput; //the StartTx request will be delayed while this Input is false std::function stopTxReadyInput; //the StopTx request will be delayed while this Input is false @@ -118,8 +120,10 @@ class Connector { bool ocppPermitsCharge(); +#if MO_ENABLE_CONNECTOR_LOCK void setOnUnlockConnector(std::function unlockConnector); std::function getOnUnlockConnector(); +#endif //MO_ENABLE_CONNECTOR_LOCK void setStartTxReadyInput(std::function startTxReady); void setStopTxReadyInput(std::function stopTxReady); diff --git a/src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h b/src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h index 127e4bba..41e3958d 100644 --- a/src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h +++ b/src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h @@ -7,6 +7,13 @@ #include +// Connector-lock related behavior (i.e. if UnlockConnectorOnEVSideDisconnect is RW; enable HW binding for UnlockConnector) +#ifndef MO_ENABLE_CONNECTOR_LOCK +#define MO_ENABLE_CONNECTOR_LOCK 1 +#endif + +#if MO_ENABLE_CONNECTOR_LOCK + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -25,4 +32,5 @@ typedef enum { } #endif // __cplusplus +#endif // MO_ENABLE_CONNECTOR_LOCK #endif // MO_UNLOCKCONNECTORRESULT_H diff --git a/src/MicroOcpp/Operations/UnlockConnector.cpp b/src/MicroOcpp/Operations/UnlockConnector.cpp index 9a171711..e67220e8 100644 --- a/src/MicroOcpp/Operations/UnlockConnector.cpp +++ b/src/MicroOcpp/Operations/UnlockConnector.cpp @@ -27,41 +27,53 @@ void UnlockConnector::processReq(JsonObject payload) { return; } - unlockConnector = connector->getOnUnlockConnector(); +#if MO_ENABLE_CONNECTOR_LOCK + { + unlockConnector = connector->getOnUnlockConnector(); - if (!unlockConnector) { - // NotSupported - return; - } + if (!unlockConnector) { + // NotSupported + return; + } - connector->endTransaction(nullptr, "UnlockCommand"); - connector->updateTxNotification(TxNotification::RemoteStop); + connector->endTransaction(nullptr, "UnlockCommand"); + connector->updateTxNotification(TxNotification::RemoteStop); - cbUnlockResult = unlockConnector(); + cbUnlockResult = unlockConnector(); - timerStart = mocpp_tick_ms(); + timerStart = mocpp_tick_ms(); + } +#endif //MO_ENABLE_CONNECTOR_LOCK } std::unique_ptr UnlockConnector::createConf() { - if (unlockConnector && mocpp_tick_ms() - timerStart < MO_UNLOCK_TIMEOUT) { - //do poll and if more time is needed, delay creation of conf msg - if (cbUnlockResult == UnlockConnectorResult_Pending) { - cbUnlockResult = unlockConnector(); + const char *status = "NotSupported"; + +#if MO_ENABLE_CONNECTOR_LOCK + if (unlockConnector) { + + if (mocpp_tick_ms() - timerStart < MO_UNLOCK_TIMEOUT) { + //do poll and if more time is needed, delay creation of conf msg + if (cbUnlockResult == UnlockConnectorResult_Pending) { - return nullptr; //no result yet - delay confirmation response + cbUnlockResult = unlockConnector(); + if (cbUnlockResult == UnlockConnectorResult_Pending) { + return nullptr; //no result yet - delay confirmation response + } } } + + if (cbUnlockResult == UnlockConnectorResult_Unlocked) { + status = "Unlocked"; + } else { + status = "UnlockFailed"; + } } +#endif //MO_ENABLE_CONNECTOR_LOCK auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); JsonObject payload = doc->to(); - if (!unlockConnector) { - payload["status"] = "NotSupported"; - } else if (cbUnlockResult == UnlockConnectorResult_Unlocked) { - payload["status"] = "Unlocked"; - } else { - payload["status"] = "UnlockFailed"; - } + payload["status"] = status; return doc; } diff --git a/src/MicroOcpp/Operations/UnlockConnector.h b/src/MicroOcpp/Operations/UnlockConnector.h index ba4081dd..bf49d195 100644 --- a/src/MicroOcpp/Operations/UnlockConnector.h +++ b/src/MicroOcpp/Operations/UnlockConnector.h @@ -18,9 +18,12 @@ namespace Ocpp16 { class UnlockConnector : public Operation { private: Model& model; + +#if MO_ENABLE_CONNECTOR_LOCK std::function unlockConnector; UnlockConnectorResult cbUnlockResult; unsigned long timerStart = 0; //for timeout +#endif //MO_ENABLE_CONNECTOR_LOCK const char *errorCode = nullptr; public: diff --git a/src/MicroOcpp_c.cpp b/src/MicroOcpp_c.cpp index 5aa119f3..04aa5091 100644 --- a/src/MicroOcpp_c.cpp +++ b/src/MicroOcpp_c.cpp @@ -120,6 +120,7 @@ MicroOcpp::OnReceiveErrorListener adaptFn(OnCallError fn) { }; } +#if MO_ENABLE_CONNECTOR_LOCK std::function adaptFn(PollUnlockResult fn) { return [fn] () {return fn();}; } @@ -127,6 +128,7 @@ std::function adaptFn(PollUnlockResult fn) { std::function adaptFn(unsigned int connectorId, PollUnlockResult_m fn) { return [fn, connectorId] () {return fn(connectorId);}; } +#endif //MO_ENABLE_CONNECTOR_LOCK void ocpp_beginTransaction(const char *idTag) { beginTransaction(idTag); @@ -281,12 +283,15 @@ void ocpp_addMeterValueInput_m(unsigned int connectorId, MeterValueInput *meterV addMeterValueInput(std::move(svs), connectorId); } + +#if MO_ENABLE_CONNECTOR_LOCK void ocpp_setOnUnlockConnectorInOut(PollUnlockResult onUnlockConnectorInOut) { setOnUnlockConnectorInOut(adaptFn(onUnlockConnectorInOut)); } void ocpp_setOnUnlockConnectorInOut_m(unsigned int connectorId, PollUnlockResult_m onUnlockConnectorInOut) { setOnUnlockConnectorInOut(adaptFn(connectorId, onUnlockConnectorInOut), connectorId); } +#endif //MO_ENABLE_CONNECTOR_LOCK void ocpp_setStartTxReadyInput(InputBool startTxReady) { setStartTxReadyInput(adaptFn(startTxReady)); diff --git a/src/MicroOcpp_c.h b/src/MicroOcpp_c.h index 52736638..64699337 100644 --- a/src/MicroOcpp_c.h +++ b/src/MicroOcpp_c.h @@ -41,8 +41,11 @@ typedef void (*OutputFloat)(float limit); typedef void (*OutputFloat_m)(unsigned int connectorId, float limit); typedef void (*OutputSmartCharging)(float power, float current, int nphases); typedef void (*OutputSmartCharging_m)(unsigned int connectorId, float power, float current, int nphases); + +#if MO_ENABLE_CONNECTOR_LOCK typedef UnlockConnectorResult (*PollUnlockResult)(); typedef UnlockConnectorResult (*PollUnlockResult_m)(unsigned int connectorId); +#endif //MO_ENABLE_CONNECTOR_LOCK #ifdef __cplusplus @@ -156,8 +159,10 @@ void ocpp_setStopTxReadyInput_m(unsigned int connectorId, InputBool_m stopTxRead void ocpp_setTxNotificationOutput(void (*notificationOutput)(OCPP_Transaction*, enum OCPP_TxNotification)); void ocpp_setTxNotificationOutput_m(unsigned int connectorId, void (*notificationOutput)(unsigned int, OCPP_Transaction*, enum OCPP_TxNotification)); +#if MO_ENABLE_CONNECTOR_LOCK void ocpp_setOnUnlockConnectorInOut(PollUnlockResult onUnlockConnectorInOut); void ocpp_setOnUnlockConnectorInOut_m(unsigned int connectorId, PollUnlockResult_m onUnlockConnectorInOut); +#endif //MO_ENABLE_CONNECTOR_LOCK /* * Access further information about the internal state of the library diff --git a/tests/Api.cpp b/tests/Api.cpp index b716965f..9f53aa94 100644 --- a/tests/Api.cpp +++ b/tests/Api.cpp @@ -62,7 +62,10 @@ TEST_CASE( "C++ API test" ) { setStartTxReadyInput([c = &checkpoints[ncheck++]] () -> bool {*c = true; return true;}); setStopTxReadyInput([c = &checkpoints[ncheck++]] () -> bool {*c = true; return true;}); setTxNotificationOutput([c = &checkpoints[ncheck++]] (MicroOcpp::Transaction*, MicroOcpp::TxNotification) {*c = true;}); + +#if MO_ENABLE_CONNECTOR_LOCK setOnUnlockConnectorInOut([c = &checkpoints[ncheck++]] () -> UnlockConnectorResult {*c = true; return UnlockConnectorResult_Unlocked;}); +#endif //MO_ENABLE_CONNECTOR_LOCK setOnResetNotify([c = &checkpoints[ncheck++]] (bool) -> bool {*c = true; return true;}); setOnResetExecute([c = &checkpoints[ncheck++]] (bool) {*c = true;}); @@ -248,8 +251,14 @@ TEST_CASE( "C API test" ) { ocpp_setStopTxReadyInput_m(2, [] (unsigned int) -> bool {checkpointsc[23] = true; return true;}); ncheckc++; ocpp_setTxNotificationOutput([] (OCPP_Transaction*, OCPP_TxNotification) {checkpointsc[24] = true;}); ncheckc++; ocpp_setTxNotificationOutput_m(2, [] (unsigned int, OCPP_Transaction*, OCPP_TxNotification) {checkpointsc[25] = true;}); ncheckc++; + +#if MO_ENABLE_CONNECTOR_LOCK ocpp_setOnUnlockConnectorInOut([] () -> UnlockConnectorResult {checkpointsc[26] = true; return UnlockConnectorResult_Unlocked;}); ncheckc++; ocpp_setOnUnlockConnectorInOut_m(2, [] (unsigned int) -> UnlockConnectorResult {checkpointsc[27] = true; return UnlockConnectorResult_Unlocked;}); ncheckc++; +#else + checkpointsc[26] = true; + checkpointsc[27] = true; +#endif //MO_ENABLE_CONNECTOR_LOCK ocpp_setOnResetNotify([] (bool) -> bool {checkpointsc[28] = true; return true;}); ncheckc++; ocpp_setOnResetExecute([] (bool) {checkpointsc[29] = true;}); ncheckc++; diff --git a/tests/ChargingSessions.cpp b/tests/ChargingSessions.cpp index 1877f0d8..6975fea6 100644 --- a/tests/ChargingSessions.cpp +++ b/tests/ChargingSessions.cpp @@ -704,6 +704,8 @@ TEST_CASE( "Charging sessions" ) { REQUIRE( checkProcessed ); REQUIRE( isTransactionRunning() ); // NotSupported doesn't lead to transaction stop +#if MO_ENABLE_CONNECTOR_LOCK + setOnUnlockConnectorInOut([] () -> UnlockConnectorResult { // connector lock fails return UnlockConnectorResult_UnlockFailed; @@ -754,6 +756,12 @@ TEST_CASE( "Charging sessions" ) { mtime += MO_UNLOCK_TIMEOUT; // increment clock so that MO_UNLOCK_TIMEOUT expires loop(); REQUIRE( checkProcessed ); + +#else + endTransaction(); + loop(); +#endif //MO_ENABLE_CONNECTOR_LOCK + } SECTION("TxStartPoint - PowerPathClosed") { From 3f130dce9dfaf7ad1b4027cbdcabb286bcc0abb9 Mon Sep 17 00:00:00 2001 From: matth-x <63792403+matth-x@users.noreply.github.com> Date: Sun, 9 Jun 2024 11:02:33 +0200 Subject: [PATCH 2/3] change default for MO_ENABLE_CONNECTOR_LOCK to 0 --- CMakeLists.txt | 1 + src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46e42ef8..5b7c959c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,6 +189,7 @@ target_compile_definitions(mo_unit_tests PUBLIC MO_ChargingScheduleMaxPeriods=4 MO_MaxChargingProfilesInstalled=3 MO_ENABLE_CERT_MGMT=1 + MO_ENABLE_CONNECTOR_LOCK=1 ) target_compile_options(mo_unit_tests PUBLIC diff --git a/src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h b/src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h index 41e3958d..0d863f2d 100644 --- a/src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h +++ b/src/MicroOcpp/Model/ConnectorBase/UnlockConnectorResult.h @@ -9,7 +9,7 @@ // Connector-lock related behavior (i.e. if UnlockConnectorOnEVSideDisconnect is RW; enable HW binding for UnlockConnector) #ifndef MO_ENABLE_CONNECTOR_LOCK -#define MO_ENABLE_CONNECTOR_LOCK 1 +#define MO_ENABLE_CONNECTOR_LOCK 0 #endif #if MO_ENABLE_CONNECTOR_LOCK From ff831cc842397a8837a7d7a0e4276b619e861c7b Mon Sep 17 00:00:00 2001 From: matth-x <63792403+matth-x@users.noreply.github.com> Date: Sun, 9 Jun 2024 11:04:00 +0200 Subject: [PATCH 3/3] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff9e04e4..b6ef80ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Changed - Change `MicroOcpp::ChargePointStatus` into C-style enum ([#309](https://github.com/matth-x/MicroOcpp/pull/309)) +- Connector lock disabled by default per `MO_ENABLE_CONNECTOR_LOCK` ([#312](https://github.com/matth-x/MicroOcpp/pull/312)) ### Added