// SPDX-License-Identifier: Apache-2.0 // Copyright chargebyte GmbH and Contributors to EVerest #include "Evse.hpp" namespace methods { RPCDataTypes::EVSEGetInfoResObj Evse::get_info(const int32_t evse_index) { RPCDataTypes::EVSEGetInfoResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } const auto data = evse->evseinfo.get_data(); if (not data.has_value()) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorNoDataAvailable; return res; } res.info = data.value(); res.error = RPCDataTypes::ResponseErrorEnum::NoError; return res; } RPCDataTypes::EVSEGetStatusResObj Evse::get_status(const int32_t evse_index) { RPCDataTypes::EVSEGetStatusResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } const auto data = evse->evsestatus.get_data(); if (not data.has_value()) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorNoDataAvailable; return res; } res.status = data.value(); res.error = RPCDataTypes::ResponseErrorEnum::NoError; return res; } RPCDataTypes::EVSEGetHardwareCapabilitiesResObj Evse::get_hardware_capabilities(const int32_t evse_index) { RPCDataTypes::EVSEGetHardwareCapabilitiesResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } const auto data = evse->hardwarecapabilities.get_data(); if (not data.has_value()) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorNoDataAvailable; return res; } res.hardware_capabilities = data.value(); return res; } RPCDataTypes::ErrorResObj Evse::set_charging_allowed(const int32_t evse_index, bool charging_allowed) { RPCDataTypes::ErrorResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } return m_request_handler_ptr->set_charging_allowed(evse_index, charging_allowed); } RPCDataTypes::EVSEGetMeterDataResObj Evse::get_meter_data(const int32_t evse_index) { RPCDataTypes::EVSEGetMeterDataResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } const auto data = evse->meterdata.get_data(); if (not data.has_value()) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorNoDataAvailable; return res; } res.meter_data = data.value(); return res; } RPCDataTypes::ErrorResObj Evse::set_ac_charging(const int32_t evse_index, bool charging_allowed, float max_current, std::optional phase_count) { RPCDataTypes::ErrorResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } return m_request_handler_ptr->set_ac_charging(evse_index, charging_allowed, max_current, phase_count); } RPCDataTypes::ErrorResObj Evse::set_ac_charging_current(const int32_t evse_index, float max_current) { RPCDataTypes::ErrorResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } return m_request_handler_ptr->set_ac_charging_current(evse_index, max_current); } RPCDataTypes::ErrorResObj Evse::set_ac_charging_phase_count(const int32_t evse_index, int phase_count) { RPCDataTypes::ErrorResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } // Check if the requested phase count is equal to the current active phase count // If so, we can return a success response without making any changes. Phase switching is not // necessary in this case. auto evse_status = evse->evsestatus.get_data(); if (evse_status.has_value() && evse_status.value().ac_charge_status.has_value()) { if (evse_status.value().ac_charge_status.value().evse_active_phase_count == phase_count) { res.error = RPCDataTypes::ResponseErrorEnum::NoError; return res; } } // If phase switching must be performed and the hardware capabilities do not allow it // we return an error response. auto hardwarecapabilities = evse->hardwarecapabilities.get_data(); if (hardwarecapabilities.has_value() && hardwarecapabilities.value().phase_switch_during_charging == false) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorOperationNotSupported; return res; } // Check if the requested phase count is within the allowed range if ((hardwarecapabilities.has_value() && phase_count < hardwarecapabilities.value().min_phase_count_export) || phase_count > hardwarecapabilities.value().max_phase_count_export) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorOutOfRange; return res; } // Check if phases are 1 or 3, otherwise return an error if (phase_count != 1 && phase_count != 3) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidParameter; return res; } return m_request_handler_ptr->set_ac_charging_phase_count(evse_index, phase_count); } RPCDataTypes::ErrorResObj Evse::set_dc_charging(const int32_t evse_index, bool charging_allowed, float max_power) { RPCDataTypes::ErrorResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } return m_request_handler_ptr->set_dc_charging(evse_index, charging_allowed, max_power); } RPCDataTypes::ErrorResObj Evse::set_dc_charging_power(const int32_t evse_index, float max_power) { RPCDataTypes::ErrorResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } return m_request_handler_ptr->set_dc_charging_power(evse_index, max_power); } RPCDataTypes::ErrorResObj Evse::enable_connector(const int32_t evse_index, int connector_index, bool enable, int priority) { RPCDataTypes::ErrorResObj res{}; const auto* evse = m_dataobj.get_evse_store(evse_index); if (!evse) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidEVSEIndex; return res; } // Iterate through the connectors to find the one with the given ID const auto connectors = evse->evseinfo.get_available_connectors(); auto it = std::find_if(connectors.begin(), connectors.end(), [connector_index](const auto& connector) { return connector.index == connector_index; }); // If not found, return an error if (it == connectors.end()) { res.error = RPCDataTypes::ResponseErrorEnum::ErrorInvalidConnectorIndex; return res; } return m_request_handler_ptr->enable_connector(evse_index, connector_index, enable, priority); } } // namespace methods