mirror of
https://github.com/uhi22/pyPLC.git
synced 2024-11-10 01:05:42 +00:00
state machines for PEV and EVSE completed until precharge.
This commit is contained in:
parent
40dcb1681c
commit
13cd9378ce
3 changed files with 246 additions and 71 deletions
107
exiConnector.py
107
exiConnector.py
|
@ -51,20 +51,35 @@ import json
|
||||||
# remove the 8 bytes V2GTP header
|
# remove the 8 bytes V2GTP header
|
||||||
# 8000dbab9371d3234b71d1b981899189d191818991d26b9b3a232b30020000040040
|
# 8000dbab9371d3234b71d1b981899189d191818991d26b9b3a232b30020000040040
|
||||||
exiHexDemoSupportedApplicationProtocolRequestIoniq="8000dbab9371d3234b71d1b981899189d191818991d26b9b3a232b30020000040040"
|
exiHexDemoSupportedApplicationProtocolRequestIoniq="8000dbab9371d3234b71d1b981899189d191818991d26b9b3a232b30020000040040"
|
||||||
# Command line:
|
# Command line:
|
||||||
# ./OpenV2G.exe DH8000dbab9371d3234b71d1b981899189d191818991d26b9b3a232b30020000040040
|
# ./OpenV2G.exe DH8000dbab9371d3234b71d1b981899189d191818991d26b9b3a232b30020000040040
|
||||||
|
|
||||||
|
|
||||||
# (2) From OpenV2G main_example.appHandshake()
|
# (2) From OpenV2G main_example.appHandshake()
|
||||||
# 8000ebab9371d34b9b79d189a98989c1d191d191818981d26b9b3a232b30010000040001b75726e3a64696e3a37303132313a323031323a4d73674465660020000100880
|
# 8000ebab9371d34b9b79d189a98989c1d191d191818981d26b9b3a232b30010000040001b75726e3a64696e3a37303132313a323031323a4d73674465660020000100880
|
||||||
exiHexDemoSupportedApplicationProtocolRequest2="8000ebab9371d34b9b79d189a98989c1d191d191818981d26b9b3a232b30010000040001b75726e3a64696e3a37303132313a323031323a4d73674465660020000100880"
|
exiHexDemoSupportedApplicationProtocolRequest2="8000ebab9371d34b9b79d189a98989c1d191d191818981d26b9b3a232b30010000040001b75726e3a64696e3a37303132313a323031323a4d73674465660020000100880"
|
||||||
# Command line:
|
# Command line:
|
||||||
# ./OpenV2G.exe DH8000ebab9371d34b9b79d189a98989c1d191d191818981d26b9b3a232b30010000040001b75726e3a64696e3a37303132313a323031323a4d73674465660020000100880
|
# ./OpenV2G.exe DH8000ebab9371d34b9b79d189a98989c1d191d191818981d26b9b3a232b30010000040001b75726e3a64696e3a37303132313a323031323a4d73674465660020000100880
|
||||||
|
|
||||||
# (3) SupportedApplicationProtocolResponse
|
# (3) SupportedApplicationProtocolResponse
|
||||||
# 80400040
|
# 80400040
|
||||||
# Command line:
|
# Command line:
|
||||||
# ./OpenV2G.exe DH80400040
|
# ./OpenV2G.exe DH80400040
|
||||||
|
|
||||||
|
# (4) SessionSetupRequest DIN
|
||||||
|
# 809a0011d00000
|
||||||
|
# Command line:
|
||||||
|
# ./OpenV2G.exe DD809a0011d00000
|
||||||
|
|
||||||
|
# (5) SessionSetupResponse DIN
|
||||||
|
# 809a02004080c1014181c211e0000080
|
||||||
|
# ./OpenV2G.exe DD809a02004080c1014181c211e0000080
|
||||||
|
|
||||||
|
# (6) CableCheckReq
|
||||||
|
# "result": "809a001010400000"
|
||||||
|
|
||||||
|
# (7) PreChargeReq
|
||||||
|
# "result": "809a001150400000c80006400000"
|
||||||
|
|
||||||
|
|
||||||
# Configuration of the exi converter tool
|
# Configuration of the exi converter tool
|
||||||
|
@ -140,7 +155,7 @@ def exiDecode(exiHex, prefix="DH"):
|
||||||
exiHex = exiByteArrayToHex(exiHex)
|
exiHex = exiByteArrayToHex(exiHex)
|
||||||
#print("type is " + str(type(exiHex)))
|
#print("type is " + str(type(exiHex)))
|
||||||
param1 = prefix + exiHex # DH for decode handshake
|
param1 = prefix + exiHex # DH for decode handshake
|
||||||
print("exiDecode: trying to decode " + exiHex + " with schema " + prefix)
|
#print("exiDecode: trying to decode " + exiHex + " with schema " + prefix)
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
[pathToOpenV2GExe, param1], capture_output=True, text=True)
|
[pathToOpenV2GExe, param1], capture_output=True, text=True)
|
||||||
#print("stdout:", result.stdout)
|
#print("stdout:", result.stdout)
|
||||||
|
@ -159,7 +174,7 @@ def exiEncode(strMessageName, params=""):
|
||||||
strConverterResult = "exiEncode ERROR. stderr:" + result.stderr
|
strConverterResult = "exiEncode ERROR. stderr:" + result.stderr
|
||||||
print(strConverterResult)
|
print(strConverterResult)
|
||||||
else:
|
else:
|
||||||
print("exiEncode stdout:", result.stdout)
|
#print("exiEncode stdout:", result.stdout)
|
||||||
# Now we have an encoder result in json form, something like:
|
# Now we have an encoder result in json form, something like:
|
||||||
# {
|
# {
|
||||||
# "info": "",
|
# "info": "",
|
||||||
|
@ -169,7 +184,7 @@ def exiEncode(strMessageName, params=""):
|
||||||
try:
|
try:
|
||||||
y = json.loads(result.stdout)
|
y = json.loads(result.stdout)
|
||||||
strConverterResult = y["result"]
|
strConverterResult = y["result"]
|
||||||
print("strConverterResult is " + str(strConverterResult))
|
#print("strConverterResult is " + str(strConverterResult))
|
||||||
except:
|
except:
|
||||||
strConverterResult = "exiEncode failed to convert json to dict."
|
strConverterResult = "exiEncode failed to convert json to dict."
|
||||||
print(strConverterResult)
|
print(strConverterResult)
|
||||||
|
@ -186,27 +201,53 @@ def testByteArrayConversion(s):
|
||||||
print("with V2GTP header=" + exiWithHeaderString)
|
print("with V2GTP header=" + exiWithHeaderString)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def testDecoder(strHex, pre="DH", comment=""):
|
||||||
print("Testing exiConnector...")
|
global nFail
|
||||||
testByteArrayConversion("123456")
|
print("Decoder test for " + comment + " with data " + strHex)
|
||||||
testByteArrayConversion("1234567")
|
decoded=exiDecode(strHex, pre)
|
||||||
testByteArrayConversion("ABCDEF")
|
print(decoded)
|
||||||
testByteArrayConversion("00112233445566778899AABBCCDDEEFF")
|
strExpected = comment
|
||||||
testByteArrayConversion("TRASH!")
|
if (decoded.find(strExpected)>0):
|
||||||
|
print("---pass---")
|
||||||
print("Testing exiDecode with exiHexDemoSupportedApplicationProtocolRequestIoniq")
|
else:
|
||||||
print(exiDecode(exiHexDemoSupportedApplicationProtocolRequestIoniq))
|
print("---***!!!FAIL!!!***---")
|
||||||
print("Testing exiDecode with exiHexDemoSupportedApplicationProtocolRequest2")
|
nFail+=1
|
||||||
strConverterResult = exiDecode(exiHexDemoSupportedApplicationProtocolRequest2)
|
|
||||||
print(strConverterResult)
|
|
||||||
|
|
||||||
strConverterResult = exiDecode(exiHexToByteArray(exiHexDemoSupportedApplicationProtocolRequest2))
|
|
||||||
print(strConverterResult)
|
|
||||||
|
|
||||||
if (strConverterResult.find("ProtocolNamespace=urn:din")>0):
|
|
||||||
print("Detected DIN")
|
if __name__ == "__main__":
|
||||||
|
nFail=0
|
||||||
|
print("Testing exiConnector...")
|
||||||
|
#testByteArrayConversion("123456")
|
||||||
|
#testByteArrayConversion("1234567")
|
||||||
|
#testByteArrayConversion("ABCDEF")
|
||||||
|
#testByteArrayConversion("00112233445566778899AABBCCDDEEFF")
|
||||||
|
#testByteArrayConversion("TRASH!")
|
||||||
|
|
||||||
|
testDecoder("8000ebab9371d34b9b79d189a98989c1d191d191818981d26b9b3a232b30010000040001b75726e3a64696e3a37303132313a323031323a4d73674465660020000100880", pre="DH", comment="supportedAppProtocolReq")
|
||||||
|
testDecoder("80400040", pre="DH", comment="supportedAppProtocolRes")
|
||||||
|
|
||||||
|
testDecoder("809a0011d00000", pre="DD", comment="SessionSetupReq")
|
||||||
|
testDecoder("809a02004080c1014181c211e0000080", pre="DD", comment="SessionSetupRes")
|
||||||
|
testDecoder("809a001198", pre="DD", comment="ServiceDiscoveryReq")
|
||||||
|
testDecoder("809a0011a0012002412104", pre="DD", comment="ServiceDiscoveryRes")
|
||||||
|
testDecoder("809a0011b2001280", pre="DD", comment="ServicePaymentSelectionReq")
|
||||||
|
testDecoder("809a0011c000", pre="DD", comment="ServicePaymentSelectionRes")
|
||||||
|
testDecoder("809a00107211400dc0c8c82324701900", pre="DD", comment="ChargeParameterDiscoveryReq")
|
||||||
|
testDecoder("809a001080004820400000c99002062050193080c0c802064c8010190140c80a20", pre="DD", comment="ChargeParameterDiscoveryRes")
|
||||||
|
testDecoder("809a001010400000", pre="DD", comment="CableCheckReq")
|
||||||
|
testDecoder("809a0010200200000000", pre="DD", comment="CableCheckRes")
|
||||||
|
testDecoder("809a001150400000c80006400000", pre="DD", comment="PreChargeReq")
|
||||||
|
testDecoder("809a00116002000000320000", pre="DD", comment="PreChargeRes")
|
||||||
|
print("Number of fails: " + str(nFail))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
param1 = "ED1" # ED for encode DIN, session setup response
|
#print("Testing exiDecode with exiHexDemoSupportedApplicationProtocolRequestIoniq")
|
||||||
result = subprocess.run([pathToOpenV2GExe, param1], capture_output=True, text=True)
|
#print(exiDecode(exiHexDemoSupportedApplicationProtocolRequestIoniq))
|
||||||
print("stdout:", result.stdout)
|
#print("Testing exiDecode with exiHexDemoSupportedApplicationProtocolRequest2")
|
||||||
print("stderr:", result.stderr)
|
#strConverterResult = exiDecode(exiHexDemoSupportedApplicationProtocolRequest2)
|
||||||
|
#print(strConverterResult)
|
||||||
|
|
||||||
|
#strConverterResult = exiDecode(exiHexToByteArray(exiHexDemoSupportedApplicationProtocolRequest2))
|
||||||
|
#print(strConverterResult)
|
||||||
|
|
86
fsmEvse.py
86
fsmEvse.py
|
@ -12,9 +12,9 @@ from exiConnector import * # for EXI data handling/converting
|
||||||
stateWaitForSupportedApplicationProtocolRequest = 0
|
stateWaitForSupportedApplicationProtocolRequest = 0
|
||||||
stateWaitForSessionSetupRequest = 1
|
stateWaitForSessionSetupRequest = 1
|
||||||
stateWaitForServiceDiscoveryRequest = 2
|
stateWaitForServiceDiscoveryRequest = 2
|
||||||
stateWaitForPaymentServiceSelectionRequest = 3
|
stateWaitForServicePaymentSelectionRequest = 3
|
||||||
stateWaitForAuthorizationRequest = 4
|
stateWaitForAuthorizationRequest = 4
|
||||||
stateWaitForChargeParameterRequest = 5
|
stateWaitForChargeParameterDiscoveryRequest = 5
|
||||||
stateWaitForCableCheckRequest = 6
|
stateWaitForCableCheckRequest = 6
|
||||||
stateWaitForPreChargeRequest = 7
|
stateWaitForPreChargeRequest = 7
|
||||||
stateWaitForPowerDeliveryRequest = 8
|
stateWaitForPowerDeliveryRequest = 8
|
||||||
|
@ -34,7 +34,6 @@ class fsmEvse():
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
print("In state WaitForSupportedApplicationProtocolRequest, received " + prettyHexMessage(self.rxData))
|
print("In state WaitForSupportedApplicationProtocolRequest, received " + prettyHexMessage(self.rxData))
|
||||||
exidata = removeV2GTPHeader(self.rxData)
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
print("received exi" + prettyHexMessage(exidata))
|
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
strConverterResult = exiDecode(exidata, "DH") # Decode Handshake-request
|
strConverterResult = exiDecode(exidata, "DH") # Decode Handshake-request
|
||||||
print(strConverterResult)
|
print(strConverterResult)
|
||||||
|
@ -45,69 +44,115 @@ class fsmEvse():
|
||||||
msg = addV2GTPHeader(exiEncode("Eh"))
|
msg = addV2GTPHeader(exiEncode("Eh"))
|
||||||
print("responding " + prettyHexMessage(msg))
|
print("responding " + prettyHexMessage(msg))
|
||||||
self.Tcp.transmit(msg)
|
self.Tcp.transmit(msg)
|
||||||
self.enterState(1)
|
self.enterState(stateWaitForSessionSetupRequest)
|
||||||
|
|
||||||
def stateFunctionWaitForSessionSetupRequest(self):
|
def stateFunctionWaitForSessionSetupRequest(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
print("In state stateFunctionWaitForSessionSetupRequest, received " + prettyHexMessage(self.rxData))
|
print("In state stateFunctionWaitForSessionSetupRequest, received " + prettyHexMessage(self.rxData))
|
||||||
exidata = removeV2GTPHeader(self.rxData)
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
print("received exi" + prettyHexMessage(exidata))
|
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
strConverterResult = exiDecode(exidata)
|
strConverterResult = exiDecode(exidata, "DD")
|
||||||
print(strConverterResult)
|
print(strConverterResult)
|
||||||
if (True):
|
if (strConverterResult.find("SessionSetupReq")>0):
|
||||||
# todo: check the request content, and fill response parameters
|
# todo: check the request content, and fill response parameters
|
||||||
msg = addV2GTPHeader(exiEncode("EDa")) # EDa for Encode, Din, SessionSetupResponse
|
msg = addV2GTPHeader(exiEncode("EDa")) # EDa for Encode, Din, SessionSetupResponse
|
||||||
print("responding " + prettyHexMessage(msg))
|
print("responding " + prettyHexMessage(msg))
|
||||||
self.Tcp.transmit(msg)
|
self.Tcp.transmit(msg)
|
||||||
self.enterState(2)
|
self.enterState(stateWaitForServiceDiscoveryRequest)
|
||||||
if (self.isTooLong()):
|
if (self.isTooLong()):
|
||||||
self.enterState(0)
|
self.enterState(0)
|
||||||
|
|
||||||
def stateFunctionWaitForServiceDiscoveryRequest(self):
|
def stateFunctionWaitForServiceDiscoveryRequest(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForServiceDiscoveryRequest, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
self.enterState(3)
|
strConverterResult = exiDecode(exidata, "DD")
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("ServiceDiscoveryReq")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDb")) # EDb for Encode, Din, ServiceDiscoveryResponse
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForServicePaymentSelectionRequest)
|
||||||
if (self.isTooLong()):
|
if (self.isTooLong()):
|
||||||
self.enterState(0)
|
self.enterState(0)
|
||||||
|
|
||||||
def stateFunctionWaitForPaymentServiceSelectionRequest(self):
|
def stateFunctionWaitForServicePaymentSelectionRequest(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForServicePaymentSelectionRequest, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
self.enterState(4)
|
strConverterResult = exiDecode(exidata, "DD")
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("ServicePaymentSelectionReq")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDc")) # EDc for Encode, Din, ServicePaymentSelectionResponse
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForChargeParameterDiscoveryRequest)
|
||||||
if (self.isTooLong()):
|
if (self.isTooLong()):
|
||||||
self.enterState(0)
|
self.enterState(0)
|
||||||
|
|
||||||
def stateFunctionWaitForAuthorizationRequest(self):
|
def stateFunctionWaitForAuthorizationRequest(self): # not specified in the DIN
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
self.enterState(5)
|
self.enterState(5)
|
||||||
if (self.isTooLong()):
|
if (self.isTooLong()):
|
||||||
self.enterState(0)
|
self.enterState(0)
|
||||||
|
|
||||||
def stateFunctionWaitForChargeParameterRequest(self):
|
def stateFunctionWaitForChargeParameterDiscoveryRequest(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForChargeParameterDiscoveryRequest, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
self.enterState(6)
|
strConverterResult = exiDecode(exidata, "DD")
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("ChargeParameterDiscoveryReq")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDe")) # EDe for Encode, Din, ChargeParameterDiscoveryResponse
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForCableCheckRequest)
|
||||||
if (self.isTooLong()):
|
if (self.isTooLong()):
|
||||||
self.enterState(0)
|
self.enterState(0)
|
||||||
|
|
||||||
def stateFunctionWaitForCableCheckRequest(self):
|
def stateFunctionWaitForCableCheckRequest(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForCableCheckRequest, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
self.enterState(7)
|
strConverterResult = exiDecode(exidata, "DD")
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("CableCheckReq")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDf")) # EDf for Encode, Din, CableCheckResponse
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForPreChargeRequest)
|
||||||
if (self.isTooLong()):
|
if (self.isTooLong()):
|
||||||
self.enterState(0)
|
self.enterState(0)
|
||||||
|
|
||||||
def stateFunctionWaitForPreChargeRequest(self):
|
def stateFunctionWaitForPreChargeRequest(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForPreChargeRequest, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
self.enterState(8)
|
strConverterResult = exiDecode(exidata, "DD")
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("PreChargeReq")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDg")) # EDf for Encode, Din, PreChargeResponse
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForPowerDeliveryRequest)
|
||||||
if (self.isTooLong()):
|
if (self.isTooLong()):
|
||||||
self.enterState(0)
|
self.enterState(0)
|
||||||
|
|
||||||
def stateFunctionWaitForPowerDeliveryRequest(self):
|
def stateFunctionWaitForPowerDeliveryRequest(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForPowerDeliveryRequest, received " + prettyHexMessage(self.rxData))
|
||||||
|
print("Todo: Reaction in state WaitForPowerDeliveryRequest is not implemented yet.")
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
self.enterState(0)
|
self.enterState(0)
|
||||||
if (self.isTooLong()):
|
if (self.isTooLong()):
|
||||||
|
@ -118,9 +163,9 @@ class fsmEvse():
|
||||||
stateWaitForSupportedApplicationProtocolRequest: stateFunctionWaitForSupportedApplicationProtocolRequest,
|
stateWaitForSupportedApplicationProtocolRequest: stateFunctionWaitForSupportedApplicationProtocolRequest,
|
||||||
stateWaitForSessionSetupRequest: stateFunctionWaitForSessionSetupRequest,
|
stateWaitForSessionSetupRequest: stateFunctionWaitForSessionSetupRequest,
|
||||||
stateWaitForServiceDiscoveryRequest: stateFunctionWaitForServiceDiscoveryRequest,
|
stateWaitForServiceDiscoveryRequest: stateFunctionWaitForServiceDiscoveryRequest,
|
||||||
stateWaitForPaymentServiceSelectionRequest: stateFunctionWaitForPaymentServiceSelectionRequest,
|
stateWaitForServicePaymentSelectionRequest: stateFunctionWaitForServicePaymentSelectionRequest,
|
||||||
stateWaitForAuthorizationRequest: stateFunctionWaitForAuthorizationRequest,
|
# stateWaitForAuthorizationRequest: stateFunctionWaitForAuthorizationRequest, not in DIN
|
||||||
stateWaitForChargeParameterRequest: stateFunctionWaitForChargeParameterRequest,
|
stateWaitForChargeParameterDiscoveryRequest: stateFunctionWaitForChargeParameterDiscoveryRequest,
|
||||||
stateWaitForCableCheckRequest: stateFunctionWaitForCableCheckRequest,
|
stateWaitForCableCheckRequest: stateFunctionWaitForCableCheckRequest,
|
||||||
stateWaitForPreChargeRequest: stateFunctionWaitForPreChargeRequest,
|
stateWaitForPreChargeRequest: stateFunctionWaitForPreChargeRequest,
|
||||||
stateWaitForPowerDeliveryRequest: stateFunctionWaitForPowerDeliveryRequest,
|
stateWaitForPowerDeliveryRequest: stateFunctionWaitForPowerDeliveryRequest,
|
||||||
|
@ -144,9 +189,6 @@ class fsmEvse():
|
||||||
if (self.Tcp.isRxDataAvailable()):
|
if (self.Tcp.isRxDataAvailable()):
|
||||||
self.rxData = self.Tcp.getRxData()
|
self.rxData = self.Tcp.getRxData()
|
||||||
#print("received " + str(self.rxData))
|
#print("received " + str(self.rxData))
|
||||||
#msg = "ok, you sent " + str(self.rxData)
|
|
||||||
#print("responding " + msg)
|
|
||||||
#self.Tcp.transmit(bytes(msg, "utf-8"))
|
|
||||||
# run the state machine:
|
# run the state machine:
|
||||||
self.cyclesInState += 1 # for timeout handling, count how long we are in a state
|
self.cyclesInState += 1 # for timeout handling, count how long we are in a state
|
||||||
self.stateFunctions[self.state](self)
|
self.stateFunctions[self.state](self)
|
||||||
|
|
124
fsmPev.py
124
fsmPev.py
|
@ -13,9 +13,9 @@ stateInitialized = 0
|
||||||
stateWaitForSupportedApplicationProtocolResponse = 1
|
stateWaitForSupportedApplicationProtocolResponse = 1
|
||||||
stateWaitForSessionSetupResponse = 2
|
stateWaitForSessionSetupResponse = 2
|
||||||
stateWaitForServiceDiscoveryResponse = 3
|
stateWaitForServiceDiscoveryResponse = 3
|
||||||
stateWaitForPaymentServiceSelectionResponse = 4
|
stateWaitForServicePaymentSelectionResponse = 4
|
||||||
stateWaitForAuthorizationResponse = 5
|
stateWaitForAuthorizationResponse = 5
|
||||||
stateWaitForChargeParameterResponse = 6
|
stateWaitForChargeParameterDiscoveryResponse = 6
|
||||||
stateWaitForCableCheckResponse = 7
|
stateWaitForCableCheckResponse = 7
|
||||||
stateWaitForPreChargeResponse = 8
|
stateWaitForPreChargeResponse = 8
|
||||||
stateWaitForPowerDeliveryResponse = 9
|
stateWaitForPowerDeliveryResponse = 9
|
||||||
|
@ -32,34 +32,129 @@ class fsmPev():
|
||||||
|
|
||||||
def stateFunctionInitialized(self):
|
def stateFunctionInitialized(self):
|
||||||
if (self.Tcp.isConnected):
|
if (self.Tcp.isConnected):
|
||||||
|
# we just use the initial request message from the Ioniq. It contains one entry: DIN.
|
||||||
self.Tcp.transmit(addV2GTPHeader(exiHexToByteArray(exiHexDemoSupportedApplicationProtocolRequestIoniq)))
|
self.Tcp.transmit(addV2GTPHeader(exiHexToByteArray(exiHexDemoSupportedApplicationProtocolRequestIoniq)))
|
||||||
self.enterState(stateWaitForSupportedApplicationProtocolResponse)
|
self.enterState(stateWaitForSupportedApplicationProtocolResponse)
|
||||||
|
|
||||||
def stateFunctionWaitForSupportedApplicationProtocolResponse(self):
|
def stateFunctionWaitForSupportedApplicationProtocolResponse(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
print("In state stateFunctionWaitForSupportedApplicationProtocolResponse, received " + prettyHexMessage(self.rxData))
|
print("In state WaitForSupportedApplicationProtocolResponse, received " + prettyHexMessage(self.rxData))
|
||||||
exidata = removeV2GTPHeader(self.rxData)
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
print("received exi" + prettyHexMessage(exidata))
|
|
||||||
self.rxData = []
|
self.rxData = []
|
||||||
strConverterResult = exiDecode(exidata, "Dh") # Decode Handshake-response
|
strConverterResult = exiDecode(exidata, "Dh") # Decode Handshake-response
|
||||||
print(strConverterResult)
|
print(strConverterResult)
|
||||||
# todo: evaluate the message
|
if (strConverterResult.find("supportedAppProtocolRes")>0):
|
||||||
# EDA for encode DIN, SessionSetupRequest
|
# todo: check the request content, and fill response parameters
|
||||||
msg = addV2GTPHeader(exiEncode("EDA"))
|
msg = addV2GTPHeader(exiEncode("EDA")) # EDA for Encode, Din, SessionSetupReq
|
||||||
print("sending SessionSetupRequest" + prettyHexMessage(msg))
|
print("responding " + prettyHexMessage(msg))
|
||||||
self.Tcp.transmit(msg)
|
self.Tcp.transmit(msg)
|
||||||
self.enterState(stateWaitForSessionSetupResponse)
|
self.enterState(stateWaitForSessionSetupResponse)
|
||||||
|
if (self.isTooLong()):
|
||||||
|
self.enterState(0)
|
||||||
|
|
||||||
def stateFunctionWaitForSessionSetupResponse(self):
|
def stateFunctionWaitForSessionSetupResponse(self):
|
||||||
if (len(self.rxData)>0):
|
if (len(self.rxData)>0):
|
||||||
#self.enterState(stateWaitForServiceDiscoveryResponse)
|
print("In state WaitForSessionSetupResponse, received " + prettyHexMessage(self.rxData))
|
||||||
pass
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
|
self.rxData = []
|
||||||
|
strConverterResult = exiDecode(exidata, "DD") # Decode DIN
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("SessionSetupRes")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDB")) # EDB for Encode, Din, ServiceDiscoveryRequest
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForServiceDiscoveryResponse)
|
||||||
|
if (self.isTooLong()):
|
||||||
|
self.enterState(0)
|
||||||
|
|
||||||
|
def stateFunctionWaitForServiceDiscoveryResponse(self):
|
||||||
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForServiceDiscoveryResponse, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
|
self.rxData = []
|
||||||
|
strConverterResult = exiDecode(exidata, "DD") # Decode DIN
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("ServiceDiscoveryRes")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDC")) # EDC for Encode, Din, ServicePaymentSelection
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForServicePaymentSelectionResponse)
|
||||||
|
if (self.isTooLong()):
|
||||||
|
self.enterState(0)
|
||||||
|
|
||||||
|
def stateFunctionWaitForServicePaymentSelectionResponse(self):
|
||||||
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForServicePaymentSelectionResponse, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
|
self.rxData = []
|
||||||
|
strConverterResult = exiDecode(exidata, "DD") # Decode DIN
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("ServicePaymentSelectionRes")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDE")) # EDE for Encode, Din, ChargeParameterDiscovery. We ignore Authorization, not specified in DIN.
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForChargeParameterDiscoveryResponse)
|
||||||
|
if (self.isTooLong()):
|
||||||
|
self.enterState(0)
|
||||||
|
|
||||||
|
def stateFunctionWaitForChargeParameterDiscoveryResponse(self):
|
||||||
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForChargeParameterDiscoveryResponse, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
|
self.rxData = []
|
||||||
|
strConverterResult = exiDecode(exidata, "DD") # Decode DIN
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("ChargeParameterDiscoveryRes")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDF")) # EDF for Encode, Din, CableCheck
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForCableCheckResponse)
|
||||||
|
if (self.isTooLong()):
|
||||||
|
self.enterState(0)
|
||||||
|
|
||||||
|
def stateFunctionWaitForCableCheckResponse(self):
|
||||||
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForCableCheckResponse, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
|
self.rxData = []
|
||||||
|
strConverterResult = exiDecode(exidata, "DD") # Decode DIN
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("CableCheckRes")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
msg = addV2GTPHeader(exiEncode("EDG")) # EDG for Encode, Din, PreCharge
|
||||||
|
print("responding " + prettyHexMessage(msg))
|
||||||
|
self.Tcp.transmit(msg)
|
||||||
|
self.enterState(stateWaitForPreChargeResponse)
|
||||||
|
if (self.isTooLong()):
|
||||||
|
self.enterState(0)
|
||||||
|
|
||||||
|
def stateFunctionWaitForPreChargeResponse(self):
|
||||||
|
if (len(self.rxData)>0):
|
||||||
|
print("In state WaitForPreChargeResponse, received " + prettyHexMessage(self.rxData))
|
||||||
|
exidata = removeV2GTPHeader(self.rxData)
|
||||||
|
self.rxData = []
|
||||||
|
strConverterResult = exiDecode(exidata, "DD") # Decode DIN
|
||||||
|
print(strConverterResult)
|
||||||
|
if (strConverterResult.find("PreChargeRes")>0):
|
||||||
|
# todo: check the request content, and fill response parameters
|
||||||
|
print("PreCharge aknowledge received.")
|
||||||
|
print("As Demo, we stay in PreCharge until the timeout elapses.")
|
||||||
|
if (self.isTooLong()):
|
||||||
|
self.enterState(0)
|
||||||
|
|
||||||
stateFunctions = {
|
stateFunctions = {
|
||||||
stateInitialized: stateFunctionInitialized,
|
stateInitialized: stateFunctionInitialized,
|
||||||
stateWaitForSupportedApplicationProtocolResponse: stateFunctionWaitForSupportedApplicationProtocolResponse,
|
stateWaitForSupportedApplicationProtocolResponse: stateFunctionWaitForSupportedApplicationProtocolResponse,
|
||||||
stateWaitForSessionSetupResponse: stateFunctionWaitForSessionSetupResponse,
|
stateWaitForSessionSetupResponse: stateFunctionWaitForSessionSetupResponse,
|
||||||
|
stateWaitForServiceDiscoveryResponse: stateFunctionWaitForServiceDiscoveryResponse,
|
||||||
|
stateWaitForServicePaymentSelectionResponse: stateFunctionWaitForServicePaymentSelectionResponse,
|
||||||
|
stateWaitForChargeParameterDiscoveryResponse: stateFunctionWaitForChargeParameterDiscoveryResponse,
|
||||||
|
stateWaitForCableCheckResponse: stateFunctionWaitForCableCheckResponse,
|
||||||
|
stateWaitForPreChargeResponse: stateFunctionWaitForPreChargeResponse,
|
||||||
}
|
}
|
||||||
|
|
||||||
def reInit(self):
|
def reInit(self):
|
||||||
|
@ -83,10 +178,7 @@ class fsmPev():
|
||||||
#self.Tcp.mainfunction() # call the lower-level worker
|
#self.Tcp.mainfunction() # call the lower-level worker
|
||||||
if (self.Tcp.isRxDataAvailable()):
|
if (self.Tcp.isRxDataAvailable()):
|
||||||
self.rxData = self.Tcp.getRxData()
|
self.rxData = self.Tcp.getRxData()
|
||||||
print("received " + prettyHexMessage(self.rxData))
|
#print("received " + prettyHexMessage(self.rxData))
|
||||||
#msg = "ok, you sent " + str(self.rxData)
|
|
||||||
#print("responding " + msg)
|
|
||||||
#self.Tcp.transmit(bytes(msg, "utf-8"))
|
|
||||||
# run the state machine:
|
# run the state machine:
|
||||||
self.cyclesInState += 1 # for timeout handling, count how long we are in a state
|
self.cyclesInState += 1 # for timeout handling, count how long we are in a state
|
||||||
self.stateFunctions[self.state](self)
|
self.stateFunctions[self.state](self)
|
||||||
|
|
Loading…
Reference in a new issue