Skip to content

Commit

Permalink
Relaxed contactor status check for DC.
Browse files Browse the repository at this point in the history
  • Loading branch information
shalinnijel2 committed Apr 30, 2024
1 parent 54a4e2e commit 35447c4
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 50 deletions.
23 changes: 11 additions & 12 deletions iso15118/secc/states/din_spec_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,17 @@ async def process_message(
return

if not self.cable_check_req_was_received:
# Requirement in 6.4.3.106 of the IEC 61851-23
# Any relays in the DC output circuit of the DC station shall
# be closed during the insulation test
if not await self.comm_session.evse_controller.is_contactor_closed():
self.stop_state_machine(
"Contactor didnt close for Cable Check",
message,
ResponseCode.FAILED,
)
return

# First CableCheckReq received. Start cable check.
await self.comm_session.evse_controller.start_cable_check()
self.cable_check_req_was_received = True
Expand All @@ -483,25 +494,13 @@ async def process_message(
# [V2G-DC-418] Stay in CableCheck state until EVSEProcessing is complete.
# Until EVSEProcessing is completed, EV will send identical
# CableCheckReq message.

evse_processing: EVSEProcessing = EVSEProcessing.ONGOING
response_code: ResponseCode = ResponseCode.OK
next_state: Type["State"] = None
if isolation_level in [
IsolationLevel.VALID,
IsolationLevel.WARNING,
]:
# Requirement in 6.4.3.106 of the IEC 61851-23
# Any relays in the DC output circuit of the DC station shall
# be closed during the insulation test
if not await self.comm_session.evse_controller.is_contactor_closed():
self.stop_state_machine(
"Contactor didnt close for Cable Check",
message,
ResponseCode.FAILED,
)
return

if isolation_level == IsolationLevel.WARNING:
logger.warning(
"Isolation resistance measured by EVSE is in Warning-Range"
Expand Down
53 changes: 31 additions & 22 deletions iso15118/secc/states/iso15118_20_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,8 @@ class DCCableCheck(StateSECC):
def __init__(self, comm_session: SECCCommunicationSession):
super().__init__(comm_session, Timeouts.V2G_EVCC_COMMUNICATION_SETUP_TIMEOUT)
self.cable_check_req_was_received = False
self.cable_check_started = False
self.contactors_closed_for_cable_check: Optional[bool] = None

async def process_message(
self,
Expand All @@ -1608,42 +1610,49 @@ async def process_message(
await SessionStop(self.comm_session).process_message(message, message_exi)
return

if not self.cable_check_req_was_received:
# First DCCableCheckReq received. Start cable check.
await self.comm_session.evse_controller.start_cable_check()
self.cable_check_req_was_received = True

next_state = None
processing = EVSEProcessing.ONGOING
isolation_level = (
await self.comm_session.evse_controller.get_cable_check_status()
)

if isolation_level in [IsolationLevel.VALID, IsolationLevel.WARNING]:
if not self.cable_check_req_was_received:
# Requirement in 6.4.3.106 of the IEC 61851-23
# Any relays in the DC output circuit of the DC station shall
# be closed during the insulation test
if not await self.comm_session.evse_controller.is_contactor_closed():
self.contactors_closed_for_cable_check = (
await self.comm_session.evse_controller.is_contactor_closed()
)
self.cable_check_req_was_received = True

if self.contactors_closed_for_cable_check is not None:
if not self.contactors_closed_for_cable_check:
self.stop_state_machine(
"Contactor didnt close for Cable Check",
message,
ResponseCode.FAILED,
)
return

if isolation_level == IsolationLevel.WARNING:
logger.warning(
"Isolation resistance measured by EVSE is in Warning range"
)
next_state = DCPreCharge
processing = EVSEProcessing.FINISHED
elif isolation_level in [IsolationLevel.INVALID, IsolationLevel.FAULT]:
self.stop_state_machine(
f"Isolation Failure: {isolation_level}",
message,
ResponseCode.FAILED,
await self.comm_session.evse_controller.start_cable_check()
self.cable_check_started = True

if self.cable_check_started:
isolation_level = (
await self.comm_session.evse_controller.get_cable_check_status()
)
return

if isolation_level in [IsolationLevel.VALID, IsolationLevel.WARNING]:
if isolation_level == IsolationLevel.WARNING:
logger.warning(
"Isolation resistance measured by EVSE is in Warning range"
)
next_state = DCPreCharge
processing = EVSEProcessing.FINISHED
elif isolation_level in [IsolationLevel.INVALID, IsolationLevel.FAULT]:
self.stop_state_machine(
f"Isolation Failure: {isolation_level}",
message,
ResponseCode.FAILED,
)
return

dc_cable_check_res = DCCableCheckRes(
header=MessageHeader(
Expand Down
22 changes: 11 additions & 11 deletions iso15118/secc/states/iso15118_2_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -2215,6 +2215,17 @@ async def process_message(
return

if not self.cable_check_req_was_received:
# Requirement in 6.4.3.106 of the IEC 61851-23
# Any relays in the DC output circuit of the DC station shall
# be closed during the insulation test
if not await self.comm_session.evse_controller.is_contactor_closed():
self.stop_state_machine(
"Contactor didnt close for Cable Check",
message,
ResponseCode.FAILED,
)
return

# First CableCheckReq received. Start cable check.
await self.comm_session.evse_controller.start_cable_check()
self.cable_check_req_was_received = True
Expand All @@ -2233,17 +2244,6 @@ async def process_message(
IsolationLevel.VALID,
IsolationLevel.WARNING,
]:
# Requirement in 6.4.3.106 of the IEC 61851-23
# Any relays in the DC output circuit of the DC station shall
# be closed during the insulation test
if not await self.comm_session.evse_controller.is_contactor_closed():
self.stop_state_machine(
"Contactor didnt close for Cable Check",
message,
ResponseCode.FAILED,
)
return

if isolation_level == IsolationLevel.WARNING:
logger.warning(
"Isolation resistance measured by EVSE is in Warning-Range"
Expand Down
34 changes: 29 additions & 5 deletions tests/iso15118_20/secc/test_iso15118_20_dc_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,34 @@ async def test_15118_20_schedule_exchange_res(
"cable_check_status, "
"expected_state",
[
(False, False, IsolationLevel.VALID, Terminate),
(False, True, None, None),
(False, True, IsolationLevel.VALID, DCPreCharge),
(True, True, None, None),
(True, True, IsolationLevel.VALID, DCPreCharge),
(False, None, None, None), # First request.
(True, None, None, None), # Not first request. Contactor status unknown.
(True, True, None, None), # Not first request. Contactor closed.
(True, False, None, Terminate), # Contactor close failed.
(
True,
True,
IsolationLevel.VALID,
DCPreCharge,
), # noqa Contactor closed. Isolation response received - Valid. Next stage Precharge.
(
True,
True,
IsolationLevel.INVALID,
Terminate,
), # noqa Contactor closed. Isolation response received - Invalid. Terminate.
(
True,
True,
IsolationLevel.WARNING,
DCPreCharge,
), # noqa Contactor closed. Isolation response received - Warning. Next stage Precharge.
(
True,
True,
IsolationLevel.FAULT,
Terminate,
), # noqa Contactor closed. Isolation response received - Fault. Terminate session.
],
)
async def test_15118_20_dc_cable_check(
Expand All @@ -228,6 +251,7 @@ async def test_15118_20_dc_cable_check(
):
dc_cable_check = DCCableCheck(self.comm_session)
dc_cable_check.cable_check_req_was_received = cable_check_req_received
dc_cable_check.contactors_closed_for_cable_check = is_contactor_closed
contactor_status = AsyncMock(return_value=is_contactor_closed)
self.comm_session.evse_controller.is_contactor_closed = contactor_status
cable_check_status = AsyncMock(return_value=cable_check_status)
Expand Down

0 comments on commit 35447c4

Please sign in to comment.