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

Jtt 770 return ongoing if cs is not ready #387

Merged
merged 6 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 1 addition & 3 deletions iso15118/secc/controller/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 3 additions & 5 deletions iso15118/secc/controller/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down
52 changes: 34 additions & 18 deletions iso15118/secc/states/iso15118_20_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
CertificateInstallationReq,
ChargeProgress,
ChargingSession,
DynamicScheduleExchangeResParams,
EIMAuthSetupResParams,
EVPowerProfile,
MatchedService,
Expand Down Expand Up @@ -457,7 +458,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 (
Expand Down Expand Up @@ -931,25 +931,39 @@ async def process_message(
ev_data_context.update_schedule_exchange_parameters(
control_mode, schedule_exchange_req
)
evse_processing = Processing.ONGOING

# 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,
schedule_exchange_req,
)
if params:

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 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 type(params) is ScheduledScheduleExchangeResParams:
self.comm_session.offered_schedules_V20 = params.schedule_tuples
else:
evse_processing = Processing.ONGOING

schedule_exchange_res = ScheduleExchangeRes(
header=MessageHeader(
Expand All @@ -960,10 +974,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.
Expand Down