Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

K01: Implement Full Validate Profile Method & Required Methods #611

Merged
merged 23 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7e028df
tests: Rename K01.FR.39 tests
christopher-davis-afs Mar 19, 2024
a681cdc
Added K01.FR06 duplication check for dates
couryrr-afs Apr 18, 2024
01b0b4f
Adding deleted tests back
couryrr-afs Apr 25, 2024
424fd9f
Adding 2.0 validate ChargingStationMaxProfile
folkengine Apr 26, 2024
1a68494
Updated validate_charging_station_max_profile to only pass in evseid
folkengine Apr 26, 2024
a09115c
Added new enum variants to the conversion function
folkengine Apr 26, 2024
067aff4
smart_charging: Use evse_id instead of evse instance for TxProfiles
christopher-davis-afs Apr 22, 2024
46b1f5a
smart_charging: Add string conversion for duplicate profile validity …
christopher-davis-afs May 1, 2024
7e8dbed
K01: Implement full validate profile function
christopher-davis-afs Apr 17, 2024
b25191d
smart_charging: Conform profiles in full validate profile method
christopher-davis-afs Apr 25, 2024
182f927
smart_charging: Implement K01 FRs 44, 45, and 49 for the charging sta…
christopher-davis-afs May 7, 2024
54cceac
SmartCharging: Implement K01.FR.26
christopher-davis-afs May 14, 2024
59af05e
smart_charging: Add tests for valid profiles
christopher-davis-afs May 28, 2024
bcef2fa
smart_charging: Refactor setting validity period values
christopher-davis-afs Jun 4, 2024
15c24c1
smart_charging: Make individual validate methods protected
christopher-davis-afs Jun 4, 2024
22627f9
smart_charging, charge_point: Use shared_ptr for DeviceModel
christopher-davis-afs Jun 4, 2024
23da8e3
smart_charging: Implement K01.FR.20
christopher-davis-afs May 29, 2024
6b516b6
smart_charging: Clean up UUID usage in tests
christopher-davis-afs Jun 7, 2024
5abf8f6
smart_charging: Remove extraneous datetime from tests
christopher-davis-afs Jun 20, 2024
ecc31ab
smart_charging: Fix spelling mistake in tests
christopher-davis-afs Jun 20, 2024
28f3470
smart_charging: Clarify validate_profile schedule test
christopher-davis-afs Jun 20, 2024
4971d68
smart_charging: Add positive test for K01FR20
christopher-davis-afs Jun 20, 2024
6e18aaa
smart_charging: Remove extraneous +1 from test
christopher-davis-afs Jun 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions doc/ocpp_201_status.md
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ This document contains the status of which OCPP 2.0.1 numbered requirements have
| K01.FR.03 | :no_entry_sign: | |
| K01.FR.04 | :white_check_mark: | |
| K01.FR.05 | | |
| K01.FR.06 | | |
| K01.FR.06 | :white_check_mark: | |
| K01.FR.07 | | |
| K01.FR.08 | :no_entry_sign: | |
| K01.FR.09 | | |
Expand All @@ -1157,10 +1157,10 @@ This document contains the status of which OCPP 2.0.1 numbered requirements have
| K01.FR.16 | | |
| K01.FR.17 | | |
| K01.FR.19 | | |
| K01.FR.20 | :white_check_mark: | |
| K01.FR.20 | :white_check_mark: | This FR hints that `ACPhaseSwitchingSupported` should be per EVSE, but this makes no sense with the rest of the spec. |
| K01.FR.21 | | |
| K01.FR.22 | | |
| K01.FR.26 | | |
| K01.FR.26 | :white_check_mark: | |
| K01.FR.27 | | |
| K01.FR.28 | | |
| K01.FR.29 | | |
Expand All @@ -1172,7 +1172,7 @@ This document contains the status of which OCPP 2.0.1 numbered requirements have
| K01.FR.35 | | |
| K01.FR.36 | :white_check_mark: | |
| K01.FR.37 | | |
| K01.FR.38 | | |
| K01.FR.38 | :white_check_mark: | |
| K01.FR.39 | :white_check_mark: | |
| K01.FR.40 | :white_check_mark: | |
| K01.FR.41 | :white_check_mark: | |
Expand Down Expand Up @@ -1218,7 +1218,7 @@ This document contains the status of which OCPP 2.0.1 numbered requirements have
| --- | --- | --- |
| K04.FR.01 | | |
| K04.FR.02 | | |
| K04.FR.03 | | |
| K04.FR.03 | :white_check_mark: | |
| K04.FR.04 | | The same as K01.FR.21 |
| K04.FR.05 | | This should be handled by the user of libocpp |
## SmartCharging - Remote Start Transaction with Charging Profile
Expand Down
3 changes: 2 additions & 1 deletion include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include <future>
#include <memory>
#include <set>

#include <ocpp/common/charging_station_base.hpp>
Expand Down Expand Up @@ -393,7 +394,7 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa

// utility
std::unique_ptr<MessageQueue<v201::MessageType>> message_queue;
std::unique_ptr<DeviceModel> device_model;
std::shared_ptr<DeviceModel> device_model;
std::shared_ptr<DatabaseHandler> database_handler;

std::map<int32_t, AvailabilityChange> scheduled_change_availability_requests;
Expand Down
45 changes: 39 additions & 6 deletions include/ocpp/v201/smart_charging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
#ifndef OCPP_V201_SMART_CHARGING_HPP
#define OCPP_V201_SMART_CHARGING_HPP

#include "ocpp/v201/device_model.hpp"
#include "ocpp/v201/enums.hpp"
#include <limits>

#include <memory>
#include <ocpp/v201/database_handler.hpp>
#include <ocpp/v201/evse.hpp>
#include <ocpp/v201/ocpp_types.hpp>
Expand All @@ -19,6 +21,7 @@ const int DEFAULT_AND_MAX_NUMBER_PHASES = 3;
enum class ProfileValidationResultEnum {
Valid,
EvseDoesNotExist,
InvalidProfileType,
TxProfileMissingTransactionId,
TxProfileEvseIdNotGreaterThanZero,
TxProfileTransactionNotOnEvse,
Expand All @@ -28,11 +31,16 @@ enum class ProfileValidationResultEnum {
ChargingProfileFirstStartScheduleIsNotZero,
ChargingProfileMissingRequiredStartSchedule,
ChargingProfileExtraneousStartSchedule,
ChargingScheduleChargingRateUnitUnsupported,
ChargingSchedulePeriodsOutOfOrder,
ChargingSchedulePeriodInvalidPhaseToUse,
ChargingSchedulePeriodUnsupportedNumberPhases,
ChargingSchedulePeriodExtraneousPhaseValues,
DuplicateTxDefaultProfileFound
ChargingSchedulePeriodPhaseToUseACPhaseSwitchingUnsupported,
ChargingStationMaxProfileCannotBeRelative,
ChargingStationMaxProfileEvseIdGreaterThanZero,
DuplicateTxDefaultProfileFound,
DuplicateProfileValidityPeriod
};

namespace conversions {
Expand All @@ -48,29 +56,51 @@ std::ostream& operator<<(std::ostream& os, const ProfileValidationResultEnum val
class SmartChargingHandler {
private:
std::map<int32_t, std::unique_ptr<EvseInterface>>& evses;
std::shared_ptr<DeviceModel>& device_model;

std::shared_ptr<ocpp::v201::DatabaseHandler> database_handler;
// cppcheck-suppress unusedStructMember
std::map<int32_t, std::vector<ChargingProfile>> charging_profiles;
std::vector<ChargingProfile> station_wide_charging_profiles;

public:
explicit SmartChargingHandler(std::map<int32_t, std::unique_ptr<EvseInterface>>& evses);
explicit SmartChargingHandler(std::map<int32_t, std::unique_ptr<EvseInterface>>& evses,
std::shared_ptr<DeviceModel>& device_model);

///
/// \brief validates the given \p profile according to the specification.
/// If a profile does not have validFrom or validTo set, we conform the values
/// to a representation that fits the spec.
///
ProfileValidationResultEnum validate_profile(ChargingProfile& profile, int32_t evse_id);

///
/// \brief Adds a given \p profile and associated \p evse_id to our stored list of profiles
///
void add_profile(int32_t evse_id, ChargingProfile& profile);

protected:
///
/// \brief validates the existence of the given \p evse_id according to the specification
///
ProfileValidationResultEnum validate_evse_exists(int32_t evse_id) const;

///
/// \brief validates requirements that apply only to the ChargingStationMaxProfile \p profile
/// according to the specification
///
ProfileValidationResultEnum validate_charging_station_max_profile(const ChargingProfile& profile,
int32_t evse_id) const;

///
/// \brief validates the given \p profile and associated \p evse_id according to the specification
///
ProfileValidationResultEnum validate_tx_default_profile(const ChargingProfile& profile, int32_t evse_id) const;
ProfileValidationResultEnum validate_tx_default_profile(ChargingProfile& profile, int32_t evse_id) const;

///
/// \brief validates the given \p profile according to the specification
///
ProfileValidationResultEnum validate_tx_profile(const ChargingProfile& profile, EvseInterface& evse) const;
ProfileValidationResultEnum validate_tx_profile(const ChargingProfile& profile, int32_t evse_id) const;

/// \brief validates that the given \p profile has valid charging schedules.
/// If a profiles charging schedule period does not have a valid numberPhases,
Expand All @@ -79,13 +109,16 @@ class SmartChargingHandler {
std::optional<EvseInterface*> evse_opt = std::nullopt) const;

///
/// \brief Adds a given \p profile and associated \p evse_id to our stored list of profiles
/// \brief Checks a given \p profile and associated \p evse_id validFrom and validTo range
/// This method assumes that the existing profile will have dates set for validFrom and validTo
///
void add_profile(int32_t evse_id, ChargingProfile& profile);
bool is_overlapping_validity_period(int evse_id, const ChargingProfile& profile) const;

private:
std::vector<ChargingProfile> get_evse_specific_tx_default_profiles() const;
std::vector<ChargingProfile> get_station_wide_tx_default_profiles() const;
void conform_validity_periods(ChargingProfile& profile) const;
CurrentPhaseType get_current_phase_type(const std::optional<EvseInterface*> evse_opt) const;
};

} // namespace ocpp::v201
Expand Down
2 changes: 1 addition & 1 deletion lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ ChargePoint::ChargePoint(const std::map<int32_t, int32_t>& evse_connector_struct
EVLOG_AND_THROW(std::invalid_argument("All non-optional callbacks must be supplied"));
}

this->device_model = std::make_unique<DeviceModel>(std::move(device_model_storage));
this->device_model = std::make_shared<DeviceModel>(std::move(device_model_storage));
this->device_model->check_integrity(evse_connector_structure);

auto database_connection = std::make_unique<common::DatabaseConnection>(fs::path(core_database_path) / "cp.db");
Expand Down
Loading
Loading