Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
@@ -0,0 +1,699 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
import pytest
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
|
||||
# fmt: off
|
||||
import logging
|
||||
|
||||
from everest.testing.core_utils.controller.test_controller_interface import TestController
|
||||
|
||||
from ocpp.routing import on, create_route_map
|
||||
from ocpp.v201 import call as call201
|
||||
from ocpp.v201 import call_result as call_result201
|
||||
from ocpp.v201.enums import *
|
||||
from ocpp.v201.datatypes import *
|
||||
from everest.testing.ocpp_utils.fixtures import *
|
||||
from everest_test_utils import * # Needs to be before the datatypes below since it overrides the v201 Action enum with the v16 one
|
||||
from ocpp.v201.enums import (Action, IdTokenEnumType as IdTokenTypeEnum, SetVariableStatusEnumType, ClearCacheStatusEnumType, ConnectorStatusEnumType)
|
||||
from validations import validate_status_notification_201
|
||||
from everest.testing.core_utils._configuration.libocpp_configuration_helper import GenericOCPP2XConfigAdjustment, OCPP2XConfigVariableIdentifier
|
||||
from everest.testing.ocpp_utils.charge_point_utils import wait_for_and_validate, TestUtility, ValidationMode, validate_incoming_messages
|
||||
# fmt: on
|
||||
|
||||
log = logging.getLogger("transactionsTest")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.ocpp_version("ocpp2.0.1")
|
||||
async def test_E04(
|
||||
central_system_v201: CentralSystem,
|
||||
test_controller: TestController,
|
||||
test_utility: TestUtility,
|
||||
):
|
||||
"""
|
||||
E04.FR.01
|
||||
...
|
||||
"""
|
||||
# prepare data for the test
|
||||
evse_id1 = 1
|
||||
connector_id = 1
|
||||
|
||||
evse_id2 = 2
|
||||
|
||||
# make an unknown IdToken
|
||||
id_token = IdTokenType(id_token="8BADF00D", type=IdTokenTypeEnum.iso14443)
|
||||
|
||||
log.info(
|
||||
"##################### E04: Transaction started while charging station is offline #################"
|
||||
)
|
||||
|
||||
test_controller.start()
|
||||
charge_point_v201 = await central_system_v201.wait_for_chargepoint(
|
||||
wait_for_bootnotification=True
|
||||
)
|
||||
|
||||
# expect StatusNotification with status available
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
call201.StatusNotification(
|
||||
datetime.now().isoformat(),
|
||||
ConnectorStatusEnumType.available,
|
||||
evse_id=evse_id1,
|
||||
connector_id=connector_id,
|
||||
),
|
||||
validate_status_notification_201,
|
||||
)
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
call201.StatusNotification(
|
||||
datetime.now().isoformat(),
|
||||
ConnectorStatusEnumType.available,
|
||||
evse_id=evse_id2,
|
||||
connector_id=connector_id,
|
||||
),
|
||||
validate_status_notification_201,
|
||||
)
|
||||
|
||||
# Enable AuthCacheCtrlr
|
||||
r: call_result201.SetVariables = (
|
||||
await charge_point_v201.set_config_variables_req(
|
||||
"AuthCacheCtrlr", "Enabled", "true"
|
||||
)
|
||||
)
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[0]
|
||||
)
|
||||
assert set_variable_result.attribute_status == SetVariableStatusEnumType.accepted
|
||||
|
||||
# Enable LocalPreAuthorize
|
||||
r: call_result201.SetVariables = (
|
||||
await charge_point_v201.set_config_variables_req(
|
||||
"AuthCtrlr", "LocalPreAuthorize", "true"
|
||||
)
|
||||
)
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[0]
|
||||
)
|
||||
assert set_variable_result.attribute_status == SetVariableStatusEnumType.accepted
|
||||
|
||||
# Set AuthCacheLifeTime
|
||||
r: call_result201.SetVariables = (
|
||||
await charge_point_v201.set_config_variables_req(
|
||||
"AuthCacheCtrlr", "LifeTime", "86400"
|
||||
)
|
||||
)
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[0]
|
||||
)
|
||||
assert set_variable_result.attribute_status == SetVariableStatusEnumType.accepted
|
||||
|
||||
# Clear cache
|
||||
r: call_result201.ClearCache = await charge_point_v201.clear_cache_req()
|
||||
assert r.status == ClearCacheStatusEnumType.accepted
|
||||
|
||||
# E04.FR.03 the queued transaction messages must contain the flag 'offline' as TRUE
|
||||
|
||||
# Enable offline authorization for unknown ID
|
||||
r: call_result201.SetVariables = (
|
||||
await charge_point_v201.set_config_variables_req(
|
||||
"AuthCtrlr", "OfflineTxForUnknownIdEnabled", "true"
|
||||
)
|
||||
)
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[0]
|
||||
)
|
||||
assert set_variable_result.attribute_status == SetVariableStatusEnumType.accepted
|
||||
|
||||
# Enable AlignedDataSignReadings (Not implemented yet)
|
||||
r: call_result201.SetVariables = (
|
||||
await charge_point_v201.set_config_variables_req(
|
||||
"AlignedDataCtrlr", "SignReadings", "true"
|
||||
)
|
||||
)
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[0]
|
||||
)
|
||||
assert set_variable_result.attribute_status == SetVariableStatusEnumType.accepted
|
||||
|
||||
test_utility.messages.clear()
|
||||
|
||||
# Disconnect CS
|
||||
log.debug(" Disconnect the CS from the CSMS")
|
||||
test_controller.disconnect_websocket()
|
||||
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# swipe id tag to authorize
|
||||
test_controller.swipe(id_token.id_token)
|
||||
|
||||
# start charging session
|
||||
test_controller.plug_in()
|
||||
|
||||
# charge for 30 seconds
|
||||
await asyncio.sleep(30)
|
||||
|
||||
# swipe id tag to de-authorize
|
||||
test_controller.swipe(id_token.id_token)
|
||||
|
||||
# stop charging session
|
||||
test_controller.plug_out()
|
||||
|
||||
await asyncio.sleep(10)
|
||||
|
||||
# Connect CS
|
||||
log.debug(" Connect the CS to the CSMS")
|
||||
test_controller.connect_websocket()
|
||||
|
||||
# wait for reconnect
|
||||
charge_point_v201 = await central_system_v201.wait_for_chargepoint(
|
||||
wait_for_bootnotification=False
|
||||
)
|
||||
|
||||
# All offline generated transaction messaages must be marked offline = True
|
||||
|
||||
# should send a Transaction event C15.FR.02
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Started", "offline": True},
|
||||
)
|
||||
# should send a Transaction event C15.FR.02
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Updated", "offline": True},
|
||||
)
|
||||
# should send a Transaction event C15.FR.02
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Ended", "offline": True},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.ocpp_version("ocpp2.0.1")
|
||||
@pytest.mark.inject_csms_mock
|
||||
@pytest.mark.ocpp_config_adaptions(
|
||||
GenericOCPP2XConfigAdjustment(
|
||||
[
|
||||
(
|
||||
OCPP2XConfigVariableIdentifier(
|
||||
"OCPPCommCtrlr", "MessageTimeout", "Actual"
|
||||
),
|
||||
"1",
|
||||
),
|
||||
(
|
||||
OCPP2XConfigVariableIdentifier(
|
||||
"OCPPCommCtrlr", "MessageAttemptInterval", "Actual"
|
||||
),
|
||||
"1",
|
||||
),
|
||||
(
|
||||
OCPP2XConfigVariableIdentifier(
|
||||
"OCPPCommCtrlr", "MessageAttempts", "Actual"
|
||||
),
|
||||
"3",
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
@pytest.mark.flaky(reruns=1)
|
||||
async def test_cleanup_transaction_events_after_max_attempts_exhausted(
|
||||
central_system: CentralSystem,
|
||||
test_controller: TestController,
|
||||
test_utility: TestUtility,
|
||||
):
|
||||
"""
|
||||
Test if transaction events are properly cleaned up after the max message attempts
|
||||
...
|
||||
"""
|
||||
# prepare data for the test
|
||||
evse_id1 = 1
|
||||
connector_id = 1
|
||||
|
||||
evse_id2 = 2
|
||||
connector_id2 = 1
|
||||
|
||||
# make an unknown IdToken
|
||||
id_token = IdTokenType(id_token="8BADF00D", type=IdTokenTypeEnum.iso14443)
|
||||
|
||||
test_controller.start()
|
||||
charge_point_v201 = await central_system.wait_for_chargepoint(
|
||||
wait_for_bootnotification=True
|
||||
)
|
||||
tx_event_attempt = SetVariableDataType(attribute_value="3", attribute_type=AttributeEnumType.actual,
|
||||
component=ComponentType(name="OCPPCommCtrlr"), variable=VariableType(name="MessageAttempts", instance="TransactionEvent"))
|
||||
tx_event_interval = SetVariableDataType(attribute_value="1", attribute_type=AttributeEnumType.actual,
|
||||
component=ComponentType(name="OCPPCommCtrlr"), variable=VariableType(name="MessageAttemptInterval", instance="TransactionEvent"))
|
||||
r: call_result201.SetVariables = (
|
||||
await charge_point_v201.set_variables_req(set_variable_data=[tx_event_attempt, tx_event_interval])
|
||||
)
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[0]
|
||||
)
|
||||
assert set_variable_result.attribute_status == SetVariableStatusEnumType.accepted
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[1]
|
||||
)
|
||||
assert set_variable_result.attribute_status == SetVariableStatusEnumType.accepted
|
||||
|
||||
# expect StatusNotification with status available
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
call201.StatusNotification(
|
||||
datetime.now().isoformat(),
|
||||
ConnectorStatusEnumType.available,
|
||||
evse_id=evse_id1,
|
||||
connector_id=connector_id,
|
||||
),
|
||||
validate_status_notification_201,
|
||||
)
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
call201.StatusNotification(
|
||||
datetime.now().isoformat(),
|
||||
ConnectorStatusEnumType.available,
|
||||
evse_id=evse_id2,
|
||||
connector_id=connector_id2,
|
||||
),
|
||||
validate_status_notification_201,
|
||||
)
|
||||
|
||||
# return a CALLERROR for the transaction event
|
||||
central_system.mock.on_transaction_event.side_effect = [
|
||||
NotImplementedError()]
|
||||
|
||||
# swipe id tag to authorize
|
||||
test_controller.swipe(id_token.id_token)
|
||||
|
||||
# start charging session
|
||||
test_controller.plug_in()
|
||||
|
||||
# should send a Transaction event
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Started", "offline": False},
|
||||
)
|
||||
test_utility.validation_mode = ValidationMode.STRICT
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Started", "offline": False},
|
||||
)
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Started", "offline": False},
|
||||
)
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Updated", "offline": False},
|
||||
)
|
||||
|
||||
test_utility.validation_mode = ValidationMode.EASY
|
||||
central_system.mock.on_transaction_event.reset()
|
||||
|
||||
# respond properly to transaction events again
|
||||
central_system.mock.on_transaction_event.side_effect = [
|
||||
call_result201.TransactionEvent()
|
||||
]
|
||||
|
||||
# stop charging session
|
||||
test_controller.plug_out()
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Ended", "offline": False},
|
||||
)
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
{"evseId": 1, "connectorId": 1, "connectorStatus": "Available"},
|
||||
)
|
||||
|
||||
test_controller.stop()
|
||||
# add a sleep to allow time for reboot
|
||||
await asyncio.sleep(2)
|
||||
test_controller.start()
|
||||
|
||||
# no attempts on delivering the transaction message should be made
|
||||
assert await validate_incoming_messages(test_utility, charge_point_v201, "TransactionEvent", {}, timeout=10) is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.ocpp_version("ocpp2.0.1")
|
||||
@pytest.mark.inject_csms_mock
|
||||
@pytest.mark.ocpp_config_adaptions(
|
||||
GenericOCPP2XConfigAdjustment(
|
||||
[
|
||||
(
|
||||
OCPP2XConfigVariableIdentifier(
|
||||
"AlignedDataCtrlr", "AlignedDataTxEndedInterval", "Actual"
|
||||
),
|
||||
"5",
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
async def test_two_parallel_transactions(
|
||||
central_system: CentralSystem,
|
||||
test_controller: TestController,
|
||||
test_utility: TestUtility,
|
||||
):
|
||||
"""
|
||||
Test if two parallel transactions work
|
||||
...
|
||||
"""
|
||||
# prepare data for the test
|
||||
evse_id1 = 1
|
||||
connector_id = 1
|
||||
|
||||
evse_id2 = 2
|
||||
connector_id2 = 1
|
||||
|
||||
# make an unknown IdToken
|
||||
id_token = IdTokenType(id_token="8BADF00D", type=IdTokenTypeEnum.iso14443)
|
||||
id_token2 = IdTokenType(id_token="ABAD1DEA", type=IdTokenTypeEnum.iso14443)
|
||||
|
||||
test_controller.start()
|
||||
charge_point_v201 = await central_system.wait_for_chargepoint(
|
||||
wait_for_bootnotification=True
|
||||
)
|
||||
|
||||
# expect StatusNotification with status available
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
call201.StatusNotification(
|
||||
datetime.now().isoformat(),
|
||||
ConnectorStatusEnumType.available,
|
||||
evse_id=evse_id1,
|
||||
connector_id=connector_id,
|
||||
),
|
||||
validate_status_notification_201,
|
||||
)
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
call201.StatusNotification(
|
||||
datetime.now().isoformat(),
|
||||
ConnectorStatusEnumType.available,
|
||||
evse_id=evse_id2,
|
||||
connector_id=connector_id2,
|
||||
),
|
||||
validate_status_notification_201,
|
||||
)
|
||||
|
||||
# swipe id tag to authorize
|
||||
test_controller.swipe(id_token.id_token, connectors=[1])
|
||||
|
||||
# start charging session
|
||||
test_controller.plug_in(evse_id1)
|
||||
|
||||
# should send a Transaction event
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Started", "offline": False},
|
||||
)
|
||||
|
||||
# swipe id tag to authorize
|
||||
test_controller.swipe(id_token2.id_token, connectors=[2])
|
||||
|
||||
# start charging session
|
||||
test_controller.plug_in(evse_id2)
|
||||
|
||||
# should send a Transaction event
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Started", "offline": False},
|
||||
)
|
||||
# let transactions run for a bit
|
||||
await asyncio.sleep(10)
|
||||
# # stop charging session
|
||||
test_controller.plug_out(evse_id1)
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Ended", "offline": False},
|
||||
)
|
||||
test_controller.plug_out(evse_id2)
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Ended", "offline": False},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.ocpp_version("ocpp2.0.1")
|
||||
async def test_id_token_info_updated_in_tx_event(
|
||||
central_system_v201: CentralSystem,
|
||||
test_controller: TestController,
|
||||
test_utility: TestUtility,
|
||||
):
|
||||
# prepare data for the test
|
||||
evse_id1 = 1
|
||||
connector_id = 1
|
||||
|
||||
evse_id2 = 2
|
||||
|
||||
# make an unknown IdToken
|
||||
id_token = IdTokenType(id_token="8BADF00D", type=IdTokenTypeEnum.iso14443)
|
||||
|
||||
log.info(
|
||||
"##################### Transaction with token info updated in transaction event #################"
|
||||
)
|
||||
|
||||
test_controller.start()
|
||||
charge_point_v201 = await central_system_v201.wait_for_chargepoint(
|
||||
wait_for_bootnotification=True
|
||||
)
|
||||
|
||||
# expect StatusNotification with status available
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
call201.StatusNotification(
|
||||
datetime.now().isoformat(),
|
||||
ConnectorStatusEnumType.available,
|
||||
evse_id=evse_id1,
|
||||
connector_id=connector_id,
|
||||
),
|
||||
validate_status_notification_201,
|
||||
)
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"StatusNotification",
|
||||
call201.StatusNotification(
|
||||
datetime.now().isoformat(),
|
||||
ConnectorStatusEnumType.available,
|
||||
evse_id=evse_id2,
|
||||
connector_id=connector_id,
|
||||
),
|
||||
validate_status_notification_201,
|
||||
)
|
||||
|
||||
@on(Action.transaction_event)
|
||||
def on_transaction_event(**kwargs):
|
||||
msg = call201.TransactionEvent(**kwargs)
|
||||
if msg.id_token != None:
|
||||
msg_token = IdTokenType(**msg.id_token)
|
||||
return call_result201.TransactionEvent(
|
||||
id_token_info=IdTokenInfoType(
|
||||
status=AuthorizationStatusEnumType.accepted,
|
||||
group_id_token=IdTokenType(
|
||||
id_token="123", type=IdTokenTypeEnum.central
|
||||
),
|
||||
)
|
||||
)
|
||||
else:
|
||||
return call_result201.TransactionEvent()
|
||||
|
||||
setattr(charge_point_v201, "on_transaction_event", on_transaction_event)
|
||||
central_system_v201.chargepoint.route_map = create_route_map(
|
||||
central_system_v201.chargepoint
|
||||
)
|
||||
# swipe id tag to authorize
|
||||
test_controller.swipe(id_token.id_token)
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"Authorize",
|
||||
{},
|
||||
)
|
||||
# start charging session
|
||||
test_controller.plug_in()
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Started"},
|
||||
)
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Updated"},
|
||||
)
|
||||
|
||||
# charge for 10 seconds
|
||||
await asyncio.sleep(10)
|
||||
|
||||
@on(Action.authorize)
|
||||
def on_authorize(**kwargs):
|
||||
msg = call201.Authorize(**kwargs)
|
||||
msg_token = IdTokenType(**msg.id_token)
|
||||
return call_result201.Authorize(
|
||||
id_token_info=IdTokenInfoType(
|
||||
status=AuthorizationStatusEnumType.accepted,
|
||||
group_id_token=IdTokenType(
|
||||
id_token="123", type=IdTokenTypeEnum.central
|
||||
),
|
||||
)
|
||||
)
|
||||
setattr(charge_point_v201, "on_authorize", on_authorize)
|
||||
central_system_v201.chargepoint.route_map = create_route_map(
|
||||
central_system_v201.chargepoint
|
||||
)
|
||||
# swipe id tag to de-authorize
|
||||
id_token = IdTokenType(id_token="8BADF00A", type=IdTokenTypeEnum.iso14443)
|
||||
test_controller.swipe(id_token.id_token)
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"Authorize",
|
||||
{},
|
||||
)
|
||||
# should send a Transaction event C15.FR.02
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Ended"},
|
||||
)
|
||||
|
||||
# stop charging session
|
||||
test_controller.plug_out()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.ocpp_version("ocpp2.0.1")
|
||||
@pytest.mark.everest_core_config('everest-config-ocpp201-ps.yaml')
|
||||
@pytest.mark.use_temporary_persistent_store
|
||||
@pytest.mark.ocpp_config_adaptions(
|
||||
GenericOCPP2XConfigAdjustment(
|
||||
[
|
||||
(
|
||||
OCPP2XConfigVariableIdentifier(
|
||||
"InternalCtrlr",
|
||||
"ResumeTransactionsOnBoot",
|
||||
"Actual",
|
||||
),
|
||||
"true",
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
async def test_stop_pending_transactions(
|
||||
central_system_v201: CentralSystem,
|
||||
test_controller: TestController,
|
||||
test_utility: TestUtility,
|
||||
):
|
||||
logging.info("######### test_stop_pending_transactions #########")
|
||||
|
||||
# prepare data for the test
|
||||
evse_id = 1
|
||||
connector_id = 1
|
||||
remote_start_id = 1
|
||||
id_token = IdTokenType(id_token="DEADBEEF", type=IdTokenTypeEnum.iso14443)
|
||||
|
||||
test_controller.start()
|
||||
charge_point_v201 = await central_system_v201.wait_for_chargepoint(
|
||||
wait_for_bootnotification=True
|
||||
)
|
||||
|
||||
|
||||
await charge_point_v201.request_start_transaction_req(
|
||||
id_token=id_token, remote_start_id=remote_start_id, evse_id=evse_id
|
||||
)
|
||||
|
||||
test_controller.plug_in()
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility, charge_point_v201, "TransactionEvent", {
|
||||
"eventType": "Started"}
|
||||
)
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{"eventType": "Updated"},
|
||||
)
|
||||
|
||||
# charge for some time...
|
||||
logging.debug("Charging for a while...")
|
||||
await asyncio.sleep(2)
|
||||
|
||||
test_controller.stop()
|
||||
|
||||
await asyncio.sleep(2)
|
||||
|
||||
test_controller.start()
|
||||
|
||||
charge_point_v201 = await central_system_v201.wait_for_chargepoint(
|
||||
wait_for_bootnotification=False
|
||||
)
|
||||
|
||||
await asyncio.sleep(2)
|
||||
|
||||
assert await wait_for_and_validate(
|
||||
test_utility,
|
||||
charge_point_v201,
|
||||
"TransactionEvent",
|
||||
{
|
||||
"eventType": "Ended",
|
||||
"transactionInfo": {
|
||||
"stoppedReason": "PowerLoss"
|
||||
}
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user