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,108 @@
|
||||
active_modules:
|
||||
iso15118_car:
|
||||
module: JsCarV2G
|
||||
config_implementation:
|
||||
main:
|
||||
stack_implementation: RISE-V2G
|
||||
mqtt_base_path: everest_external/iso15118/ev
|
||||
device: auto
|
||||
connector_1:
|
||||
module: EvseManager
|
||||
config_module:
|
||||
connector_id: 1
|
||||
three_phases: true
|
||||
has_ventilation: true
|
||||
country_code: DE
|
||||
rcd_enabled: true
|
||||
evse_id: '1'
|
||||
connections:
|
||||
bsp:
|
||||
- module_id: yeti_driver
|
||||
implementation_id: board_support
|
||||
powermeter_grid_side:
|
||||
- module_id: yeti_driver
|
||||
implementation_id: powermeter
|
||||
yeti_driver:
|
||||
module: JsYetiSimulator
|
||||
slac:
|
||||
module: JsSlacSimulator
|
||||
car_simulator:
|
||||
module: JsCarSimulator
|
||||
config_module:
|
||||
auto_enable: true
|
||||
connector_id: 1
|
||||
auto_enable: true
|
||||
connections:
|
||||
simulation_control:
|
||||
- module_id: yeti_driver
|
||||
implementation_id: yeti_simulation_control
|
||||
ev:
|
||||
- module_id: iso15118_car
|
||||
implementation_id: ev
|
||||
slac:
|
||||
- module_id: slac
|
||||
implementation_id: ev
|
||||
ocpp:
|
||||
module: OCPP
|
||||
config_module:
|
||||
ChargePointConfigPath: ocpp16-config.json
|
||||
UserConfigPath: user_config.json
|
||||
EnableExternalWebsocketControl: true
|
||||
connections:
|
||||
evse_manager:
|
||||
- module_id: connector_1
|
||||
implementation_id: evse
|
||||
reservation:
|
||||
- module_id: auth
|
||||
implementation_id: reservation
|
||||
auth:
|
||||
- module_id: auth
|
||||
implementation_id: main
|
||||
system:
|
||||
- module_id: system
|
||||
implementation_id: main
|
||||
auth:
|
||||
module: Auth
|
||||
config_module:
|
||||
connection_timeout: 20
|
||||
connections:
|
||||
token_provider:
|
||||
- module_id: token_provider_manual
|
||||
implementation_id: main
|
||||
- module_id: ocpp
|
||||
implementation_id: auth_provider
|
||||
token_validator:
|
||||
- module_id: ocpp
|
||||
implementation_id: auth_validator
|
||||
evse_manager:
|
||||
- module_id: connector_1
|
||||
implementation_id: evse
|
||||
token_provider_manual:
|
||||
module: JsDummyTokenProviderManual
|
||||
connections: {}
|
||||
config_implementation:
|
||||
main:
|
||||
token: '123'
|
||||
type: dummy
|
||||
energy_manager:
|
||||
module: EnergyManager
|
||||
connections:
|
||||
energy_trunk:
|
||||
- module_id: grid_connection_point
|
||||
implementation_id: energy_grid
|
||||
grid_connection_point:
|
||||
module: EnergyNode
|
||||
config_module:
|
||||
fuse_limit_A: 63.0
|
||||
phase_count: 3
|
||||
connections:
|
||||
price_information: []
|
||||
energy_consumer:
|
||||
- module_id: connector_1
|
||||
implementation_id: energy_grid
|
||||
powermeter:
|
||||
- module_id: yeti_driver
|
||||
implementation_id: powermeter
|
||||
system:
|
||||
module: System
|
||||
x-module-layout: {}
|
||||
@@ -0,0 +1,171 @@
|
||||
active_modules:
|
||||
iso15118_charger:
|
||||
module: PyJosev
|
||||
config_module:
|
||||
device: auto
|
||||
supported_DIN70121: false
|
||||
iso15118_car:
|
||||
module: JsCarV2G
|
||||
config_implementation:
|
||||
main:
|
||||
stack_implementation: RISE-V2G
|
||||
mqtt_base_path: everest_external/iso15118/ev
|
||||
device: auto
|
||||
connector_1:
|
||||
module: EvseManager
|
||||
config_module:
|
||||
connector_id: 1
|
||||
three_phases: true
|
||||
has_ventilation: true
|
||||
country_code: DE
|
||||
rcd_enabled: true
|
||||
evse_id: "1"
|
||||
session_logging: true
|
||||
session_logging_xml: false
|
||||
ac_hlc_enabled: false
|
||||
ac_hlc_use_5percent: false
|
||||
ac_enforce_hlc: false
|
||||
connections:
|
||||
bsp:
|
||||
- module_id: yeti_driver_1
|
||||
implementation_id: board_support
|
||||
powermeter_grid_side:
|
||||
- module_id: yeti_driver_1
|
||||
implementation_id: powermeter
|
||||
slac:
|
||||
- module_id: slac
|
||||
implementation_id: evse
|
||||
hlc:
|
||||
- module_id: iso15118_charger
|
||||
implementation_id: charger
|
||||
connector_2:
|
||||
module: EvseManager
|
||||
config_module:
|
||||
connector_id: 2
|
||||
three_phases: true
|
||||
has_ventilation: true
|
||||
country_code: DE
|
||||
rcd_enabled: true
|
||||
evse_id: "2"
|
||||
session_logging: true
|
||||
session_logging_xml: false
|
||||
ac_hlc_enabled: false
|
||||
ac_hlc_use_5percent: false
|
||||
ac_enforce_hlc: false
|
||||
connections:
|
||||
bsp:
|
||||
- module_id: yeti_driver_2
|
||||
implementation_id: board_support
|
||||
powermeter_grid_side:
|
||||
- module_id: yeti_driver_2
|
||||
implementation_id: powermeter
|
||||
slac:
|
||||
- module_id: slac
|
||||
implementation_id: evse
|
||||
hlc:
|
||||
- module_id: iso15118_charger
|
||||
implementation_id: charger
|
||||
yeti_driver_1:
|
||||
module: JsYetiSimulator
|
||||
yeti_driver_2:
|
||||
module: JsYetiSimulator
|
||||
slac:
|
||||
module: JsSlacSimulator
|
||||
car_simulator_1:
|
||||
module: JsCarSimulator
|
||||
config_module:
|
||||
connector_id: 1
|
||||
auto_enable: true
|
||||
auto_exec: false
|
||||
auto_exec_commands: sleep 1;iec_wait_pwr_ready;sleep 1;draw_power_regulated 16,3;sleep 30;unplug
|
||||
connections:
|
||||
simulation_control:
|
||||
- module_id: yeti_driver_1
|
||||
implementation_id: yeti_simulation_control
|
||||
ev:
|
||||
- module_id: iso15118_car
|
||||
implementation_id: ev
|
||||
slac:
|
||||
- module_id: slac
|
||||
implementation_id: ev
|
||||
car_simulator_2:
|
||||
module: JsCarSimulator
|
||||
config_module:
|
||||
connector_id: 2
|
||||
auto_enable: true
|
||||
auto_exec: false
|
||||
connections:
|
||||
simulation_control:
|
||||
- module_id: yeti_driver_2
|
||||
implementation_id: yeti_simulation_control
|
||||
ev:
|
||||
- module_id: iso15118_car
|
||||
implementation_id: ev
|
||||
slac:
|
||||
- module_id: slac
|
||||
implementation_id: ev
|
||||
ocpp:
|
||||
module: OCPP201
|
||||
config_module:
|
||||
ChargePointConfigPath: config.json
|
||||
connections:
|
||||
evse_manager:
|
||||
- module_id: connector_1
|
||||
implementation_id: evse
|
||||
- module_id: connector_2
|
||||
implementation_id: evse
|
||||
system:
|
||||
- module_id: system
|
||||
implementation_id: main
|
||||
auth:
|
||||
module: Auth
|
||||
config_module:
|
||||
connection_timeout: 30
|
||||
selection_algorithm: PlugEvents
|
||||
connections:
|
||||
token_provider:
|
||||
- module_id: ocpp
|
||||
implementation_id: auth_provider
|
||||
- module_id: token_provider_manual
|
||||
implementation_id: main
|
||||
token_validator:
|
||||
- module_id: ocpp
|
||||
implementation_id: auth_validator
|
||||
evse_manager:
|
||||
- module_id: connector_1
|
||||
implementation_id: evse
|
||||
- module_id: connector_2
|
||||
implementation_id: evse
|
||||
token_provider_manual:
|
||||
module: JsDummyTokenProviderManual
|
||||
energy_manager:
|
||||
module: EnergyManager
|
||||
connections:
|
||||
energy_trunk:
|
||||
- module_id: grid_connection_point
|
||||
implementation_id: energy_grid
|
||||
grid_connection_point:
|
||||
module: EnergyNode
|
||||
config_module:
|
||||
fuse_limit_A: 40.0
|
||||
phase_count: 3
|
||||
connections:
|
||||
price_information: []
|
||||
energy_consumer:
|
||||
- module_id: connector_1
|
||||
implementation_id: energy_grid
|
||||
- module_id: connector_2
|
||||
implementation_id: energy_grid
|
||||
powermeter:
|
||||
- module_id: yeti_driver_1
|
||||
implementation_id: powermeter
|
||||
api:
|
||||
module: API
|
||||
connections:
|
||||
evse_manager:
|
||||
- module_id: connector_1
|
||||
implementation_id: evse
|
||||
system:
|
||||
module: System
|
||||
|
||||
x-module-layout: {}
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"Internal": {
|
||||
"ChargePointId": "cp001",
|
||||
"CentralSystemURI": "127.0.0.1:9000/cp001",
|
||||
"ChargeBoxSerialNumber": "cp001",
|
||||
"ChargePointModel": "Yeti",
|
||||
"ChargePointVendor": "Pionix",
|
||||
"FirmwareVersion": "0.1",
|
||||
"LogMessages": true
|
||||
},
|
||||
"Core": {
|
||||
"AllowOfflineTxForUnknownId": true,
|
||||
"AuthorizeRemoteTxRequests": true,
|
||||
"AuthorizationCacheEnabled": true,
|
||||
"ClockAlignedDataInterval": 900,
|
||||
"ConnectionTimeOut": 10,
|
||||
"ConnectorPhaseRotation": "0.RST,1.RST",
|
||||
"GetConfigurationMaxKeys": 100,
|
||||
"HeartbeatInterval": 86400,
|
||||
"LocalAuthorizeOffline": false,
|
||||
"LocalPreAuthorize": false,
|
||||
"MeterValuesAlignedData": "Energy.Active.Import.Register",
|
||||
"MeterValuesSampledData": "Energy.Active.Import.Register",
|
||||
"MeterValueSampleInterval": 0,
|
||||
"NumberOfConnectors": 1,
|
||||
"ResetRetries": 1,
|
||||
"StopTransactionOnEVSideDisconnect": true,
|
||||
"StopTransactionOnInvalidId": true,
|
||||
"StopTxnAlignedData": "Energy.Active.Import.Register",
|
||||
"StopTxnSampledData": "Energy.Active.Import.Register",
|
||||
"SupportedFeatureProfiles": "Core,FirmwareManagement,RemoteTrigger,Reservation,LocalAuthListManagement,SmartCharging",
|
||||
"TransactionMessageAttempts": 3,
|
||||
"TransactionMessageRetryInterval": 1,
|
||||
"UnlockConnectorOnEVSideDisconnect": true
|
||||
},
|
||||
"FirmwareManagement": {
|
||||
"SupportedFileTransferProtocols": "FTP"
|
||||
},
|
||||
"Security": {
|
||||
"AuthorizationKey": "AABBCCDDEEFFGGHH",
|
||||
"SecurityProfile": 0,
|
||||
"CpoName": "Pionix",
|
||||
"AdditionalRootCertificateCheck": false
|
||||
},
|
||||
"LocalAuthListManagement": {
|
||||
"LocalAuthListEnabled": true,
|
||||
"LocalAuthListMaxLength": 42,
|
||||
"SendLocalListMaxLength": 42
|
||||
},
|
||||
"Reservation": {
|
||||
"ReserveConnectorZeroSupported": true
|
||||
},
|
||||
"SmartCharging": {
|
||||
"ChargeProfileMaxStackLevel": 42,
|
||||
"ChargingScheduleAllowedChargingRateUnit": "Current,Power",
|
||||
"ChargingScheduleMaxPeriods": 42,
|
||||
"MaxChargingProfilesInstalled": 42
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
import shutil
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption("--everest-prefix", action="store", default="~/checkout/everest-workspace/EVerest",
|
||||
help="EVerest path; default = '~/checkout/everest-workspace/EVerest'")
|
||||
parser.addoption("--libocpp", action="store", default="~/checkout/everest-workspace/libocpp",
|
||||
help="libocpp path; default = '~/checkout/everest-workspace/libocpp'")
|
||||
|
||||
def pytest_configure(config):
|
||||
everest_prefix = config.getoption("--everest-prefix")
|
||||
shutil.copy("conf/ocpp16-config.json", f"{everest_prefix}/share/everest/modules/OCPP")
|
||||
@@ -0,0 +1,192 @@
|
||||
|
||||
import pytest
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
|
||||
from ocpp.v201 import call_result, call
|
||||
from ocpp.v201.datatypes import SetVariableResultType, IdTokenType
|
||||
from ocpp.v201.enums import SetVariableStatusType, IdTokenType as IdTokenTypeEnum, ClearCacheStatusType, ConnectorStatusType, RequestStartStopStatusType
|
||||
|
||||
from everest.testing.core_utils.controller.everest_test_controller import EverestTestController
|
||||
from everest.testing.core_utils.controller.test_controller_interface import TestController
|
||||
from everest.testing.core_utils.fixtures import *
|
||||
# noinspection PyUnresolvedReferences
|
||||
from everest.testing.ocpp_utils.fixtures import test_utility, charge_point_v16, central_system, test_config, ocpp_config, charge_point, ocpp_version
|
||||
from everest.testing.ocpp_utils.charge_point_utils import wait_for_and_validate, OcppTestConfiguration, TestUtility
|
||||
from everest.testing.ocpp_utils.charge_point_v201 import ChargePoint201
|
||||
from everest.testing.ocpp_utils.charge_point_v16 import ChargePoint16
|
||||
|
||||
|
||||
def validate_status_notification_201(meta_data, msg, exp_payload):
|
||||
return msg.payload['connectorStatus'] == exp_payload.connector_status and \
|
||||
msg.payload['evseId'] == exp_payload.evse_id and \
|
||||
msg.payload['connectorId'] == exp_payload.connector_id
|
||||
|
||||
|
||||
@ pytest.mark.asyncio
|
||||
@pytest.mark.ocpp_version("ocpp1.6")
|
||||
@pytest.mark.everest_core_config("conf/everest-config-ocpp16.yaml")
|
||||
async def test_ocpp_16(test_config: OcppTestConfiguration, charge_point_v16: ChargePoint16, test_controller: TestController, test_utility: TestUtility):
|
||||
await charge_point_v16.get_configuration_req(key=["AuthorizeRemoteTxRequests"])
|
||||
await charge_point_v16.change_configuration_req(key="MeterValueSampleInterval", value="10")
|
||||
|
||||
# send RemoteStartTransaction.req
|
||||
await charge_point_v16.remote_start_transaction_req(id_tag="DEADBEEF", connector_id=1)
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v16, "RequestStartTransactio", call_result.RequestStartTransactionPayload(status=RequestStartStopStatusType.accepted))
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v16, "StatusNotification", {"connectorId": 1, "status": "Preparing"})
|
||||
|
||||
test_controller.plug_in()
|
||||
|
||||
# expect StartTransaction.req
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v16, "StartTransaction", {
|
||||
"connectorId": 1, "idTag": "DEADBEEF", "meterStart": 0})
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v16, "StatusNotification", {"connectorId": 1, "status": "Charging"})
|
||||
|
||||
assert await charge_point_v16.remote_stop_transaction_req(transaction_id=1)
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v16, "RemoteStopTransaction", {"status": "Accepted"})
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v16, "StopTransaction", {"reason": "Remote"})
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v16, "StatusNotification", {"connectorId": 1, "status": "Finishing"})
|
||||
|
||||
test_controller.plug_out()
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v16, "StatusNotification", {"connectorId": 1, "status": "Available"})
|
||||
|
||||
|
||||
@ pytest.mark.asyncio
|
||||
@pytest.mark.ocpp_version("ocpp2.0.1")
|
||||
@pytest.mark.everest_core_config("conf/everest-config-ocpp201.yaml")
|
||||
async def test_ocpp_201(charge_point_v201: ChargePoint201, test_controller: EverestTestController, test_utility: TestUtility):
|
||||
"""This test case tests some requirements around AuthorizationCache of OCPP2.0.1
|
||||
|
||||
Args:
|
||||
charge_point_v201 (ChargePoint201): this fixture starts up a OCPP2.0.1 CSMS and EVerest connection to this CSMS using OCPP. The reference can be used to send and receive messages over OCPP
|
||||
test_controller (TestController): this fixture is used to control the simulation
|
||||
test_utility (TestUtility): this fixture carries meta data of the test case that can be used for validations
|
||||
"""
|
||||
|
||||
# prepare data for the test
|
||||
evse_id = 1
|
||||
connector_id = 1
|
||||
|
||||
# Enable AuthCacheCtrlr
|
||||
r: call_result.SetVariablesPayload = 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 == SetVariableStatusType.accepted
|
||||
|
||||
# Enable LocalPreAuthorize
|
||||
r: call_result.SetVariablesPayload = 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 == SetVariableStatusType.accepted
|
||||
|
||||
# Set AuthCacheLifeTime
|
||||
r: call_result.SetVariablesPayload = 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 == SetVariableStatusType.accepted
|
||||
|
||||
# Clear cache
|
||||
r: call_result.ClearCachePayload = await charge_point_v201.clear_cache_req()
|
||||
assert r.status == ClearCacheStatusType.accepted
|
||||
|
||||
test_controller.swipe("DEADBEEF")
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v201, "Authorize", call.AuthorizePayload(
|
||||
id_token=IdTokenType(
|
||||
id_token="DEADBEEF",
|
||||
type=IdTokenTypeEnum.iso14443
|
||||
)
|
||||
))
|
||||
|
||||
test_controller.plug_in()
|
||||
# eventType=Started
|
||||
await wait_for_and_validate(test_utility, charge_point_v201, "TransactionEvent", {"eventType": "Started"})
|
||||
test_utility.messages.clear()
|
||||
test_controller.plug_out()
|
||||
# eventType=Ended
|
||||
await wait_for_and_validate(test_utility, charge_point_v201, "TransactionEvent", {"eventType": "Ended"})
|
||||
|
||||
test_utility.messages.clear()
|
||||
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# because LocalPreAuthorize is true we dont expect an Authorize.req this time
|
||||
test_utility.forbidden_actions.append("Authorize")
|
||||
|
||||
test_controller.swipe("DEADBEEF")
|
||||
test_controller.plug_in()
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v201, "StatusNotification",
|
||||
call.StatusNotificationPayload(datetime.now().isoformat(),
|
||||
ConnectorStatusType.occupied, evse_id, connector_id),
|
||||
validate_status_notification_201)
|
||||
|
||||
# because LocalPreAuthorize is true we dont expect an authorize here
|
||||
r: call.TransactionEventPayload = call.TransactionEventPayload(**await wait_for_and_validate(test_utility, charge_point_v201,
|
||||
"TransactionEvent", {"eventType": "Started"}))
|
||||
|
||||
# Disable LocalPreAuthorize
|
||||
r: call_result.SetVariablesPayload = await charge_point_v201.set_config_variables_req("AuthCtrlr", "LocalPreAuthorize", "false")
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[0])
|
||||
assert set_variable_result.attribute_status == SetVariableStatusType.accepted
|
||||
|
||||
# Set AuthCacheLifeTime to 1s
|
||||
r: call_result.SetVariablesPayload = await charge_point_v201.set_config_variables_req("AuthCacheCtrlr", "LifeTime", "1")
|
||||
set_variable_result: SetVariableResultType = SetVariableResultType(
|
||||
**r.set_variable_result[0])
|
||||
assert set_variable_result.attribute_status == SetVariableStatusType.accepted
|
||||
|
||||
test_utility.messages.clear()
|
||||
test_controller.plug_out()
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v201, "StatusNotification",
|
||||
call.StatusNotificationPayload(datetime.now().isoformat(),
|
||||
ConnectorStatusType.available, evse_id, connector_id),
|
||||
validate_status_notification_201)
|
||||
|
||||
# eventType=Ended
|
||||
await wait_for_and_validate(test_utility, charge_point_v201,"TransactionEvent", {"eventType": "Ended"})
|
||||
|
||||
test_utility.forbidden_actions.clear()
|
||||
|
||||
test_controller.swipe("DEADBEEF")
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v201, "Authorize", call.AuthorizePayload(
|
||||
id_token=IdTokenType(
|
||||
id_token="DEADBEEF",
|
||||
type=IdTokenTypeEnum.iso14443
|
||||
)
|
||||
))
|
||||
|
||||
# Enable LocalPreAuthorize
|
||||
r: call_result.SetVariablesPayload = 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 == SetVariableStatusType.accepted
|
||||
|
||||
test_controller.plug_in()
|
||||
# eventType=Started
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v201, "TransactionEvent", {"eventType": "Started"})
|
||||
test_utility.messages.clear()
|
||||
test_controller.plug_out()
|
||||
# eventType=Ended
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v201,"TransactionEvent", {"eventType": "Ended"})
|
||||
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v201, "StatusNotification",
|
||||
call.StatusNotificationPayload(datetime.now().isoformat(),
|
||||
ConnectorStatusType.available, evse_id, connector_id),
|
||||
validate_status_notification_201)
|
||||
|
||||
# AuthCacheLifeTime expired so sending Authorize.req
|
||||
test_controller.swipe("DEADBEEF")
|
||||
assert await wait_for_and_validate(test_utility, charge_point_v201, "Authorize", call.AuthorizePayload(
|
||||
id_token=IdTokenType(
|
||||
id_token="DEADBEEF",
|
||||
type=IdTokenTypeEnum.iso14443
|
||||
)
|
||||
))
|
||||
Reference in New Issue
Block a user