From 331d0f8486206bfd8a5e48df4b598e313e089141 Mon Sep 17 00:00:00 2001 From: Shalin Nijel <89510971+shalinnijel2@users.noreply.github.com> Date: Fri, 8 Mar 2024 09:54:27 +0000 Subject: [PATCH 1/6] Return ongoing in ScheduleExchangeRes if cs is not ready --- iso15118/secc/states/iso15118_20_states.py | 40 +++++++++++++--------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/iso15118/secc/states/iso15118_20_states.py b/iso15118/secc/states/iso15118_20_states.py index 2bc0207f..dc05d761 100644 --- a/iso15118/secc/states/iso15118_20_states.py +++ b/iso15118/secc/states/iso15118_20_states.py @@ -931,25 +931,29 @@ async def process_message( ev_data_context.update_schedule_exchange_parameters( control_mode, schedule_exchange_req ) - evse_processing = Processing.ONGOING + params = await self.comm_session.evse_controller.get_schedule_exchange_params( self.comm_session.selected_energy_service, control_mode, schedule_exchange_req, ) - if params: + + if params and control_mode == ControlMode.SCHEDULED: + if type(params) is ScheduledScheduleExchangeResParams: + self.comm_session.offered_schedules_V20 = params.schedule_tuples + else: + self.stop_state_machine( + f"Unexpected control_mode {control_mode}," + f" for params type {type(params)}", + message, + ResponseCode.FAILED, + ) + return + + if self.comm_session.evse_controller.ready_to_charge(): evse_processing = Processing.FINISHED - if control_mode == ControlMode.SCHEDULED: - if type(params) is ScheduledScheduleExchangeResParams: - self.comm_session.offered_schedules_V20 = params.schedule_tuples - else: - self.stop_state_machine( - f"Unexpected control_mode {control_mode}," - f" for params type {type(params)}", - message, - ResponseCode.FAILED, - ) - return + else: + evse_processing = Processing.ONGOING schedule_exchange_res = ScheduleExchangeRes( header=MessageHeader( @@ -960,10 +964,12 @@ async def process_message( scheduled_params=params if control_mode == ControlMode.SCHEDULED else None, dynamic_params=params if control_mode == ControlMode.DYNAMIC else None, ) - evse_data_context = self.comm_session.evse_controller.evse_data_context - evse_data_context.update_schedule_exchange_parameters( - control_mode, schedule_exchange_res - ) + + if evse_processing == Processing.FINISHED: + evse_data_context = self.comm_session.evse_controller.evse_data_context + evse_data_context.update_schedule_exchange_parameters( + control_mode, schedule_exchange_res + ) # We don't know what request will come next (which state to transition to), # unless the schedule parameters are ready and we're in AC charging. From bf52b3570666ca0447abdba51be5d58cb490a3c7 Mon Sep 17 00:00:00 2001 From: Shalin Nijel <89510971+shalinnijel2@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:59:05 +0000 Subject: [PATCH 2/6] Made get_schedule_exchange_params non-optional --- iso15118/secc/controller/interface.py | 4 +--- iso15118/secc/controller/simulator.py | 8 +++----- iso15118/secc/states/iso15118_20_states.py | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/iso15118/secc/controller/interface.py b/iso15118/secc/controller/interface.py index 08ab6498..0979602d 100644 --- a/iso15118/secc/controller/interface.py +++ b/iso15118/secc/controller/interface.py @@ -160,9 +160,7 @@ async def get_schedule_exchange_params( selected_energy_service: SelectedEnergyService, control_mode: ControlMode, schedule_exchange_req: ScheduleExchangeReq, - ) -> Optional[ - Union[ScheduledScheduleExchangeResParams, DynamicScheduleExchangeResParams] - ]: + ) -> Union[ScheduledScheduleExchangeResParams, DynamicScheduleExchangeResParams]: """ Gets the parameters for a ScheduleExchangeResponse. If the parameters are not yet ready when requested, diff --git a/iso15118/secc/controller/simulator.py b/iso15118/secc/controller/simulator.py index 389c052e..f85b62a9 100644 --- a/iso15118/secc/controller/simulator.py +++ b/iso15118/secc/controller/simulator.py @@ -298,9 +298,7 @@ async def get_schedule_exchange_params( selected_energy_service: SelectedEnergyService, control_mode: ControlMode, schedule_exchange_req: ScheduleExchangeReq, - ) -> Optional[ - Union[ScheduledScheduleExchangeResParams, DynamicScheduleExchangeResParams] - ]: + ) -> Union[ScheduledScheduleExchangeResParams, DynamicScheduleExchangeResParams]: if control_mode == ControlMode.SCHEDULED: return await self.get_scheduled_se_params( selected_energy_service, schedule_exchange_req @@ -314,7 +312,7 @@ async def get_scheduled_se_params( self, selected_energy_service: SelectedEnergyService, schedule_exchange_req: ScheduleExchangeReq, - ) -> Optional[ScheduledScheduleExchangeResParams]: + ) -> ScheduledScheduleExchangeResParams: """Overrides EVSEControllerInterface.get_scheduled_se_params().""" charging_power_schedule_entry = PowerScheduleEntry( duration=3600, @@ -510,7 +508,7 @@ async def get_dynamic_se_params( self, selected_energy_service: SelectedEnergyService, schedule_exchange_req: ScheduleExchangeReq, - ) -> Optional[DynamicScheduleExchangeResParams]: + ) -> DynamicScheduleExchangeResParams: """Overrides EVSEControllerInterface.get_dynamic_se_params().""" price_level_schedule_entry = PriceLevelScheduleEntry( duration=3600, price_level=1 diff --git a/iso15118/secc/states/iso15118_20_states.py b/iso15118/secc/states/iso15118_20_states.py index dc05d761..c561c7d5 100644 --- a/iso15118/secc/states/iso15118_20_states.py +++ b/iso15118/secc/states/iso15118_20_states.py @@ -938,7 +938,7 @@ async def process_message( schedule_exchange_req, ) - if params and control_mode == ControlMode.SCHEDULED: + if control_mode == ControlMode.SCHEDULED: if type(params) is ScheduledScheduleExchangeResParams: self.comm_session.offered_schedules_V20 = params.schedule_tuples else: From 6483ef0da64ebee5fcf38e1daac7cb9eefb0eb58 Mon Sep 17 00:00:00 2001 From: Shalin Nijel <89510971+shalinnijel2@users.noreply.github.com> Date: Wed, 13 Mar 2024 15:03:24 +0000 Subject: [PATCH 3/6] Added comment --- iso15118/secc/states/iso15118_20_states.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iso15118/secc/states/iso15118_20_states.py b/iso15118/secc/states/iso15118_20_states.py index c561c7d5..02dee0e4 100644 --- a/iso15118/secc/states/iso15118_20_states.py +++ b/iso15118/secc/states/iso15118_20_states.py @@ -932,6 +932,11 @@ async def process_message( control_mode, schedule_exchange_req ) + # As per Table 49 of ISO15118-20 spec: one of scheduled_params/dynamic_params is + # required even if EVSEProcessing is ongoing. The SECC shall only omit the + # parameter 'ScheduleList' in case EVSEProcessing is set to 'Ongoing'. + # However, the schema file doesn't permit this as minOccurs = 0 is not set in + # schema here: https://github.com/SwitchEV/iso15118/blob/769eddb0cb780db629b4c736de270d381516abd1/iso15118/shared/schemas/iso15118_20/V2G_CI_CommonMessages.xsd#L467-L466 # noqa params = await self.comm_session.evse_controller.get_schedule_exchange_params( self.comm_session.selected_energy_service, control_mode, From f7a3f826401e0c94df661bad2e7df365d9e9d3b6 Mon Sep 17 00:00:00 2001 From: Shalin Nijel <89510971+shalinnijel2@users.noreply.github.com> Date: Wed, 13 Mar 2024 15:21:23 +0000 Subject: [PATCH 4/6] Removed ready to charge check from authorisation loop --- iso15118/secc/states/iso15118_20_states.py | 1 - 1 file changed, 1 deletion(-) diff --git a/iso15118/secc/states/iso15118_20_states.py b/iso15118/secc/states/iso15118_20_states.py index 02dee0e4..d048c872 100644 --- a/iso15118/secc/states/iso15118_20_states.py +++ b/iso15118/secc/states/iso15118_20_states.py @@ -457,7 +457,6 @@ async def process_message( if ( current_authorization_status.authorization_status == AuthorizationStatus.ACCEPTED - and self.comm_session.evse_controller.ready_to_charge() ): evse_processing = Processing.FINISHED elif ( From 859726c1b8ce733f138db1931c3ff8eec709c966 Mon Sep 17 00:00:00 2001 From: Shalin Nijel <89510971+shalinnijel2@users.noreply.github.com> Date: Wed, 13 Mar 2024 15:29:54 +0000 Subject: [PATCH 5/6] check params type before sending response --- iso15118/secc/states/iso15118_20_states.py | 27 +++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/iso15118/secc/states/iso15118_20_states.py b/iso15118/secc/states/iso15118_20_states.py index d048c872..5445ec02 100644 --- a/iso15118/secc/states/iso15118_20_states.py +++ b/iso15118/secc/states/iso15118_20_states.py @@ -942,20 +942,25 @@ async def process_message( schedule_exchange_req, ) - if control_mode == ControlMode.SCHEDULED: - if type(params) is ScheduledScheduleExchangeResParams: - self.comm_session.offered_schedules_V20 = params.schedule_tuples - else: - self.stop_state_machine( - f"Unexpected control_mode {control_mode}," - f" for params type {type(params)}", - message, - ResponseCode.FAILED, - ) - return + if ( + control_mode == ControlMode.SCHEDULED + and type(params) is not ScheduledScheduleExchangeResParams + ) or ( + control_mode == ControlMode.DYNAMIC + and type(params) is not DynamicScheduleExchangeResParams + ): + self.stop_state_machine( + f"Unexpected control_mode {control_mode}," + f" for params type {type(params)}", + message, + ResponseCode.FAILED, + ) + return if self.comm_session.evse_controller.ready_to_charge(): evse_processing = Processing.FINISHED + if type(params) is ScheduledScheduleExchangeResParams: + self.comm_session.offered_schedules_V20 = params.schedule_tuples else: evse_processing = Processing.ONGOING From f86dd202cab945776d626570a8c7d54166fd5a55 Mon Sep 17 00:00:00 2001 From: Shalin Nijel <89510971+shalinnijel2@users.noreply.github.com> Date: Wed, 13 Mar 2024 15:36:23 +0000 Subject: [PATCH 6/6] Fixed flake8 error --- iso15118/secc/states/iso15118_20_states.py | 1 + 1 file changed, 1 insertion(+) diff --git a/iso15118/secc/states/iso15118_20_states.py b/iso15118/secc/states/iso15118_20_states.py index 5445ec02..1d538422 100644 --- a/iso15118/secc/states/iso15118_20_states.py +++ b/iso15118/secc/states/iso15118_20_states.py @@ -53,6 +53,7 @@ CertificateInstallationReq, ChargeProgress, ChargingSession, + DynamicScheduleExchangeResParams, EIMAuthSetupResParams, EVPowerProfile, MatchedService,