From 8e59f340f41107bec204324833b26bea5ed0c5f0 Mon Sep 17 00:00:00 2001 From: Mahdi Dadashi Date: Sun, 19 Feb 2023 17:45:56 +0330 Subject: [PATCH 1/6] Update AuthentLocalList.cpp in first time of SendLocalList.req list version is (0) zero and must Accepted --- src/chargepoint/authent/AuthentLocalList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chargepoint/authent/AuthentLocalList.cpp b/src/chargepoint/authent/AuthentLocalList.cpp index 0e8769e7..fd19b740 100644 --- a/src/chargepoint/authent/AuthentLocalList.cpp +++ b/src/chargepoint/authent/AuthentLocalList.cpp @@ -124,7 +124,7 @@ bool AuthentLocalList::handleMessage(const ocpp::messages::SendLocalListReq& req // Check local list activation if (m_ocpp_config.localAuthListEnabled()) { - if (request.listVersion > 0) + if (request.listVersion >= 0) { // Check update list size if (request.localAuthorizationList.size() <= m_ocpp_config.sendLocalListMaxLength()) From f8222bcb0fbc16139df59dac318cbcd6404bde29 Mon Sep 17 00:00:00 2001 From: Mahdi Dadashi Date: Sun, 19 Feb 2023 17:50:32 +0330 Subject: [PATCH 2/6] In TriggerMessage.req connector_id is optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In TriggerMessage.req connector_id is optional and if connector_id is set by invalid value will send rejected.for meter value if the connectorId is relevant but absent, this should be interpreted as “for all allowed connectorId values”. I am not sure about send meter values for connector 0 (zero) --- .../metervalues/MeterValuesManager.cpp | 38 ++++++++++++++++--- .../trigger/TriggerMessageManager.cpp | 34 +++++++++-------- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/chargepoint/metervalues/MeterValuesManager.cpp b/src/chargepoint/metervalues/MeterValuesManager.cpp index 8eea0996..29668505 100644 --- a/src/chargepoint/metervalues/MeterValuesManager.cpp +++ b/src/chargepoint/metervalues/MeterValuesManager.cpp @@ -188,10 +188,23 @@ void MeterValuesManager::getTxStopMeterValues(unsigned int connector_id, std::ve bool MeterValuesManager::onTriggerMessage(ocpp::types::MessageTrigger message, const ocpp::types::Optional& connector_id) { bool ret = false; - if (connector_id.isSet() && (message == MessageTrigger::MeterValues)) + + if (message == MessageTrigger::MeterValues) { - processTriggered(connector_id); - ret = true; + if (connector_id.isSet()) + { + processTriggered(connector_id); + ret = true; + } + else + { + for (const Connector* connector : m_connectors.getConnectors()) + { + unsigned int id = connector->id; + processTriggered(id); + } + ret = true; + } } return ret; } @@ -201,12 +214,25 @@ bool MeterValuesManager::onTriggerMessage(ocpp::types::MessageTriggerEnumType const ocpp::types::Optional& connector_id) { bool ret = false; - if (connector_id.isSet() && (message == MessageTriggerEnumType::MeterValues)) + if (message == MessageTriggerEnumType::MeterValues) { - processTriggered(connector_id); - ret = true; + if (connector_id.isSet()) + { + processTriggered(connector_id); + ret = true; + } + else + { + for (const Connector* connector : m_connectors.getConnectors()) + { + unsigned int id = connector->id; + processTriggered(id); + } + ret = true; + } } return ret; + } /** @copydoc void IConfigChangedListener::configurationValueChanged(const std::string&) */ diff --git a/src/chargepoint/trigger/TriggerMessageManager.cpp b/src/chargepoint/trigger/TriggerMessageManager.cpp index e97b7c1b..7b80fe5c 100644 --- a/src/chargepoint/trigger/TriggerMessageManager.cpp +++ b/src/chargepoint/trigger/TriggerMessageManager.cpp @@ -85,8 +85,14 @@ bool TriggerMessageManager::handleMessage(const ocpp::messages::TriggerMessageRe } else { - // Check connector id - if (!request.connectorId.isSet() || m_connectors.isValid(request.connectorId)) + // Check invalid connector id + if (request.connectorId.isSet() && !m_connectors.isValid(request.connectorId)) + { + error_code = ocpp::rpc::IRpc::RPC_ERROR_PROPERTY_CONSTRAINT_VIOLATION; + error_message = "Invalid connector id"; + response.status = TriggerMessageStatus::Rejected; + } + else { // Call handler if (it->second->onTriggerMessage(request.requestedMessage, request.connectorId)) @@ -100,11 +106,6 @@ bool TriggerMessageManager::handleMessage(const ocpp::messages::TriggerMessageRe LOG_WARNING << "Trigger message rejected : " << trigger_message; } } - else - { - error_code = ocpp::rpc::IRpc::RPC_ERROR_PROPERTY_CONSTRAINT_VIOLATION; - error_message = "Invalid connector id"; - } } return ret; @@ -136,26 +137,27 @@ bool TriggerMessageManager::handleMessage(const ocpp::messages::ExtendedTriggerM } else { - // Check connector id - if (!request.connectorId.isSet() || m_connectors.isValid(request.connectorId)) + // Check invalid connector id + if (request.connectorId.isSet() && !m_connectors.isValid(request.connectorId)) + { + error_code = ocpp::rpc::IRpc::RPC_ERROR_PROPERTY_CONSTRAINT_VIOLATION; + error_message = "Invalid connector id"; + response.status = TriggerMessageStatusEnumType::Rejected; + } + else { // Call handler if (it->second->onTriggerMessage(request.requestedMessage, request.connectorId)) { response.status = TriggerMessageStatusEnumType::Accepted; - LOG_INFO << "Extended trigger message accepted : " << trigger_message; + LOG_INFO << "Trigger message accepted : " << trigger_message; } else { response.status = TriggerMessageStatusEnumType::Rejected; - LOG_WARNING << "Extended trigger message rejected : " << trigger_message; + LOG_WARNING << "Trigger message rejected : " << trigger_message; } } - else - { - error_code = ocpp::rpc::IRpc::RPC_ERROR_PROPERTY_CONSTRAINT_VIOLATION; - error_message = "Invalid connector id"; - } } return ret; From 10c06e608954b36d93a9416a4fc3b17ceeee6e60 Mon Sep 17 00:00:00 2001 From: Mahdi Dadashi Date: Sun, 19 Feb 2023 17:52:41 +0330 Subject: [PATCH 3/6] wrong value in m_call for reset requested --- tests/stubs/ChargePointEventsHandlerStub.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stubs/ChargePointEventsHandlerStub.cpp b/tests/stubs/ChargePointEventsHandlerStub.cpp index 806ba68f..ce30bedf 100755 --- a/tests/stubs/ChargePointEventsHandlerStub.cpp +++ b/tests/stubs/ChargePointEventsHandlerStub.cpp @@ -170,7 +170,7 @@ bool ChargePointEventsHandlerStub::getLocalLimitationsSchedule(unsigned int /** @copydoc bool IChargePointEventsHandler::resetRequested(ocpp::types::ResetType) */ bool ChargePointEventsHandlerStub::resetRequested(ocpp::types::ResetType reset_type) { - m_calls["transactionDeAuthorized"] = {{"reset_type", ResetTypeHelper.toString(reset_type)}}; + m_calls["resetRequested"] = {{"reset_type", ResetTypeHelper.toString(reset_type)}}; return callResult("resetRequested"); } From efd52720c8b2b3848fc76378c22b5da83e3ff2ac Mon Sep 17 00:00:00 2001 From: Mahdi Dadashi Date: Tue, 21 Feb 2023 15:07:31 +0000 Subject: [PATCH 4/6] retry for ever in download and upload failed when retries == 0 and operation failed , after (nb_retries-- ) command, nb_retries value equals to 0xffffffff and retry for ever --- .../maintenance/MaintenanceManager.cpp | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/chargepoint/maintenance/MaintenanceManager.cpp b/src/chargepoint/maintenance/MaintenanceManager.cpp index bde7442f..6f2e385d 100644 --- a/src/chargepoint/maintenance/MaintenanceManager.cpp +++ b/src/chargepoint/maintenance/MaintenanceManager.cpp @@ -586,9 +586,9 @@ void MaintenanceManager::processGetDiagnostics(std::string if (!success) { // Next retry - nb_retries--; - if (nb_retries != 0) + if (nb_retries > 0) { + nb_retries--; LOG_WARNING << "GetDiagnostics : upload failed (" << nb_retries << " retrie(s) left - next retry in " << retry_interval_s.count() << "s)"; std::this_thread::sleep_for(retry_interval_s); @@ -635,10 +635,12 @@ void MaintenanceManager::processUpdateFirmware(std::string ocpp::types::Optional retry_interval, ocpp::types::DateTime retrieve_date) { + + LOG_INFO << "UpdateFirmware : Waiting until retrieve date:"< DateTime::now()) { - LOG_INFO << "UpdateFirmware : Waiting until retrieve date"; std::this_thread::sleep_until(std::chrono::system_clock::from_time_t(retrieve_date.timestamp())); } @@ -667,9 +669,10 @@ void MaintenanceManager::processUpdateFirmware(std::string if (!success) { // Next retry - nb_retries--; - if (nb_retries != 0) + + if (nb_retries > 0) { + nb_retries--; LOG_WARNING << "FirmwareUpdate : download failed (" << nb_retries << " retrie(s) left - next retry in " << retry_interval_s.count() << "s)"; std::this_thread::sleep_for(retry_interval_s); @@ -766,10 +769,10 @@ void MaintenanceManager::processGetLog(ocpp::types::LogEnumType type, success = m_events_handler.uploadFile(local_log_file, url); if (!success) { - // Next retry - nb_retries--; - if (nb_retries != 0) + // Next retry + if (nb_retries > 0) { + nb_retries--; LOG_WARNING << "GetLog : upload failed (" << nb_retries << " retrie(s) left - next retry in " << retry_interval_s.count() << "s)"; std::this_thread::sleep_for(retry_interval_s); @@ -854,10 +857,10 @@ void MaintenanceManager::processSignedUpdateFirmware(std::string success = m_events_handler.downloadFile(location, local_firmware_file); if (!success) { - // Next retry - nb_retries--; - if (nb_retries != 0) + // Next retry + if (nb_retries > 0) { + nb_retries--; LOG_WARNING << "SignedUpdateFirmware : download failed (" << nb_retries << " retrie(s) left - next retry in " << retry_interval_s.count() << "s)"; std::this_thread::sleep_for(retry_interval_s); From 6450abc79eb59e90f695ad789c4c06d7ab7e8052 Mon Sep 17 00:00:00 2001 From: c-jimenez <18682655+c-jimenez@users.noreply.github.com> Date: Mon, 27 Feb 2023 08:40:23 +0100 Subject: [PATCH 5/6] =?UTF-8?q?[chargepoint]=C2=A0Code=20formatting=20on?= =?UTF-8?q?=20maintenance,=20metervlues=20and=20triggermessage=20managers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../maintenance/MaintenanceManager.cpp | 61 +++++++++++++------ .../metervalues/MeterValuesManager.cpp | 8 +-- .../trigger/TriggerMessageManager.cpp | 12 ++-- 3 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/chargepoint/maintenance/MaintenanceManager.cpp b/src/chargepoint/maintenance/MaintenanceManager.cpp index 6f2e385d..205d5443 100644 --- a/src/chargepoint/maintenance/MaintenanceManager.cpp +++ b/src/chargepoint/maintenance/MaintenanceManager.cpp @@ -589,9 +589,16 @@ void MaintenanceManager::processGetDiagnostics(std::string if (nb_retries > 0) { nb_retries--; - LOG_WARNING << "GetDiagnostics : upload failed (" << nb_retries << " retrie(s) left - next retry in " - << retry_interval_s.count() << "s)"; - std::this_thread::sleep_for(retry_interval_s); + if (nb_retries != 0) + { + LOG_WARNING << "GetDiagnostics : upload failed (" << nb_retries << " retrie(s) left - next retry in " + << retry_interval_s.count() << "s)"; + std::this_thread::sleep_for(retry_interval_s); + } + else + { + LOG_WARNING << "GetDiagnostics : upload failed no retries left"; + } } } @@ -636,7 +643,7 @@ void MaintenanceManager::processUpdateFirmware(std::string ocpp::types::DateTime retrieve_date) { - LOG_INFO << "UpdateFirmware : Waiting until retrieve date:"< DateTime::now()) @@ -669,13 +676,19 @@ void MaintenanceManager::processUpdateFirmware(std::string if (!success) { // Next retry - if (nb_retries > 0) { - nb_retries--; - LOG_WARNING << "FirmwareUpdate : download failed (" << nb_retries << " retrie(s) left - next retry in " - << retry_interval_s.count() << "s)"; - std::this_thread::sleep_for(retry_interval_s); + nb_retries--; + if (nb_retries != 0) + { + LOG_WARNING << "FirmwareUpdate : download failed (" << nb_retries << " retrie(s) left - next retry in " + << retry_interval_s.count() << "s)"; + std::this_thread::sleep_for(retry_interval_s); + } + else + { + LOG_WARNING << "FirmwareUpdate : download failed no retries left"; + } } } @@ -769,13 +782,20 @@ void MaintenanceManager::processGetLog(ocpp::types::LogEnumType type, success = m_events_handler.uploadFile(local_log_file, url); if (!success) { - // Next retry + // Next retry if (nb_retries > 0) { nb_retries--; - LOG_WARNING << "GetLog : upload failed (" << nb_retries << " retrie(s) left - next retry in " << retry_interval_s.count() - << "s)"; - std::this_thread::sleep_for(retry_interval_s); + if (nb_retries != 0) + { + LOG_WARNING << "GetLog : upload failed (" << nb_retries << " retrie(s) left - next retry in " + << retry_interval_s.count() << "s)"; + std::this_thread::sleep_for(retry_interval_s); + } + else + { + LOG_WARNING << "GetLog : upload failed retries left"; + } } } @@ -857,13 +877,20 @@ void MaintenanceManager::processSignedUpdateFirmware(std::string success = m_events_handler.downloadFile(location, local_firmware_file); if (!success) { - // Next retry + // Next retry if (nb_retries > 0) { nb_retries--; - LOG_WARNING << "SignedUpdateFirmware : download failed (" << nb_retries << " retrie(s) left - next retry in " - << retry_interval_s.count() << "s)"; - std::this_thread::sleep_for(retry_interval_s); + if (nb_retries != 0) + { + LOG_WARNING << "SignedUpdateFirmware : download failed (" << nb_retries << " retrie(s) left - next retry in " + << retry_interval_s.count() << "s)"; + std::this_thread::sleep_for(retry_interval_s); + } + else + { + LOG_WARNING << "SignedUpdateFirmware : download failed no retries left"; + } } } diff --git a/src/chargepoint/metervalues/MeterValuesManager.cpp b/src/chargepoint/metervalues/MeterValuesManager.cpp index 29668505..be9157cb 100644 --- a/src/chargepoint/metervalues/MeterValuesManager.cpp +++ b/src/chargepoint/metervalues/MeterValuesManager.cpp @@ -188,13 +188,11 @@ void MeterValuesManager::getTxStopMeterValues(unsigned int connector_id, std::ve bool MeterValuesManager::onTriggerMessage(ocpp::types::MessageTrigger message, const ocpp::types::Optional& connector_id) { bool ret = false; - if (message == MessageTrigger::MeterValues) { if (connector_id.isSet()) { processTriggered(connector_id); - ret = true; } else { @@ -203,8 +201,8 @@ bool MeterValuesManager::onTriggerMessage(ocpp::types::MessageTrigger message, c unsigned int id = connector->id; processTriggered(id); } - ret = true; } + ret = true; } return ret; } @@ -219,7 +217,6 @@ bool MeterValuesManager::onTriggerMessage(ocpp::types::MessageTriggerEnumType if (connector_id.isSet()) { processTriggered(connector_id); - ret = true; } else { @@ -228,11 +225,10 @@ bool MeterValuesManager::onTriggerMessage(ocpp::types::MessageTriggerEnumType unsigned int id = connector->id; processTriggered(id); } - ret = true; } + ret = true; } return ret; - } /** @copydoc void IConfigChangedListener::configurationValueChanged(const std::string&) */ diff --git a/src/chargepoint/trigger/TriggerMessageManager.cpp b/src/chargepoint/trigger/TriggerMessageManager.cpp index 7b80fe5c..172b6e30 100644 --- a/src/chargepoint/trigger/TriggerMessageManager.cpp +++ b/src/chargepoint/trigger/TriggerMessageManager.cpp @@ -88,8 +88,8 @@ bool TriggerMessageManager::handleMessage(const ocpp::messages::TriggerMessageRe // Check invalid connector id if (request.connectorId.isSet() && !m_connectors.isValid(request.connectorId)) { - error_code = ocpp::rpc::IRpc::RPC_ERROR_PROPERTY_CONSTRAINT_VIOLATION; - error_message = "Invalid connector id"; + error_code = ocpp::rpc::IRpc::RPC_ERROR_PROPERTY_CONSTRAINT_VIOLATION; + error_message = "Invalid connector id"; response.status = TriggerMessageStatus::Rejected; } else @@ -140,8 +140,8 @@ bool TriggerMessageManager::handleMessage(const ocpp::messages::ExtendedTriggerM // Check invalid connector id if (request.connectorId.isSet() && !m_connectors.isValid(request.connectorId)) { - error_code = ocpp::rpc::IRpc::RPC_ERROR_PROPERTY_CONSTRAINT_VIOLATION; - error_message = "Invalid connector id"; + error_code = ocpp::rpc::IRpc::RPC_ERROR_PROPERTY_CONSTRAINT_VIOLATION; + error_message = "Invalid connector id"; response.status = TriggerMessageStatusEnumType::Rejected; } else @@ -150,12 +150,12 @@ bool TriggerMessageManager::handleMessage(const ocpp::messages::ExtendedTriggerM if (it->second->onTriggerMessage(request.requestedMessage, request.connectorId)) { response.status = TriggerMessageStatusEnumType::Accepted; - LOG_INFO << "Trigger message accepted : " << trigger_message; + LOG_INFO << "Extended trigger message accepted : " << trigger_message; } else { response.status = TriggerMessageStatusEnumType::Rejected; - LOG_WARNING << "Trigger message rejected : " << trigger_message; + LOG_WARNING << "Extended trigger message rejected : " << trigger_message; } } } From da1fa377ff6e65f82bc4af80fc1dfa519ab11519 Mon Sep 17 00:00:00 2001 From: c-jimenez <18682655+c-jimenez@users.noreply.github.com> Date: Tue, 28 Feb 2023 08:25:01 +0100 Subject: [PATCH 6/6] =?UTF-8?q?[chargepoint]=C2=A0Fixed=20meter=20values?= =?UTF-8?q?=20unit=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metervalues/test_metervalues.cpp | 134 +++++++++++++++++- 1 file changed, 128 insertions(+), 6 deletions(-) diff --git a/tests/chargepoint/metervalues/test_metervalues.cpp b/tests/chargepoint/metervalues/test_metervalues.cpp index a001d861..7102a08c 100644 --- a/tests/chargepoint/metervalues/test_metervalues.cpp +++ b/tests/chargepoint/metervalues/test_metervalues.cpp @@ -162,6 +162,120 @@ static void checkClockAligned(const std::vector>>& messages, + ReadingContext context) +{ + MeterValuesReq meter_value_req; + + CHECK_EQ(messages.size(), 3u); + CHECK_EQ(messages[0].first, METER_VALUES_ACTION); + CHECK_EQ(messages[1].first, METER_VALUES_ACTION); + CHECK_EQ(messages[2].first, METER_VALUES_ACTION); + + CHECK(deserializeMeterValue((*messages[0].second), meter_value_req)); + CHECK_EQ(meter_value_req.connectorId, 0); + CHECK_FALSE(meter_value_req.transactionId.isSet()); + CHECK_EQ(meter_value_req.meterValue.size(), 1u); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue.size(), 4); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].phase, Phase::L1); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].location, Location::Inlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].value, "10"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].phase, Phase::L2); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].location, Location::Inlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].value, "20"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].phase, Phase::L3); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].location, Location::Inlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].value, "30"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].measurand, Measurand::EnergyActiveImportRegister); + CHECK_FALSE(meter_value_req.meterValue[0].sampledValue[3].phase.isSet()); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].location, Location::Inlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].unit, UnitOfMeasure::kWh); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].value, "123"); + + CHECK(deserializeMeterValue((*messages[1].second), meter_value_req)); + CHECK_EQ(meter_value_req.connectorId, 1); + CHECK_FALSE(meter_value_req.transactionId.isSet()); + CHECK_EQ(meter_value_req.meterValue.size(), 1u); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue.size(), 4); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].phase, Phase::L1); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].location, Location::Outlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].value, "40"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].phase, Phase::L2); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].location, Location::Outlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].value, "50"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].phase, Phase::L3); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].location, Location::Outlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].value, "60"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].measurand, Measurand::EnergyActiveImportRegister); + CHECK_FALSE(meter_value_req.meterValue[0].sampledValue[3].phase.isSet()); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].location, Location::Outlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].unit, UnitOfMeasure::kWh); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].value, "100"); + + CHECK(deserializeMeterValue((*messages[2].second), meter_value_req)); + CHECK_EQ(meter_value_req.connectorId, 2); + CHECK_FALSE(meter_value_req.transactionId.isSet()); + CHECK_EQ(meter_value_req.meterValue.size(), 1u); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue.size(), 4); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].phase, Phase::L1); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].location, Location::Outlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[0].value, "70"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].phase, Phase::L2); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].location, Location::Outlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[1].value, "80"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].measurand, Measurand::CurrentImport); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].phase, Phase::L3); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].location, Location::Outlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].unit, UnitOfMeasure::A); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[2].value, "90"); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].measurand, Measurand::EnergyActiveImportRegister); + CHECK_FALSE(meter_value_req.meterValue[0].sampledValue[3].phase.isSet()); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].location, Location::Outlet); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].format, ValueFormat::Raw); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].unit, UnitOfMeasure::kWh); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].context, context); + CHECK_EQ(meter_value_req.meterValue[0].sampledValue[3].value, "23"); +} + /** @brief Check the sampled meter values */ static void checkSampled(const std::vector>>& messages) { @@ -825,18 +939,26 @@ TEST_SUITE("Metervalues component") rpc.clearCalls(); // Trigger meter values without connector id - CHECK_FALSE(meter_mgr.onTriggerMessage(MessageTrigger::MeterValues, Optional())); - CHECK_FALSE(event_handler.methodCalled("getMeterValue", params)); + CHECK(meter_mgr.onTriggerMessage(MessageTrigger::MeterValues, Optional())); + CHECK(event_handler.methodCalled("getMeterValue", params)); // Check messages - CHECK(rpc.getCalls().empty()); + checkAllSampled(rpc.getCalls(), ReadingContext::Trigger); + + // Clear stubs + event_handler.clearCalls(); + rpc.clearCalls(); // Extended trigger meter values without connector id - CHECK_FALSE(meter_mgr.onTriggerMessage(MessageTriggerEnumType::MeterValues, Optional())); - CHECK_FALSE(event_handler.methodCalled("getMeterValue", params)); + CHECK(meter_mgr.onTriggerMessage(MessageTriggerEnumType::MeterValues, Optional())); + CHECK(event_handler.methodCalled("getMeterValue", params)); // Check messages - CHECK(rpc.getCalls().empty()); + checkAllSampled(rpc.getCalls(), ReadingContext::Trigger); + + // Clear stubs + event_handler.clearCalls(); + rpc.clearCalls(); } TEST_CASE("Custom meter values")