diff --git a/fsmEvse.py b/fsmEvse.py index 395ed79..bd921b0 100644 --- a/fsmEvse.py +++ b/fsmEvse.py @@ -105,6 +105,12 @@ class fsmEvse(): stateWaitForPowerDeliveryRequest: stateFunctionWaitForPowerDeliveryRequest, } + def reInit(self): + print("re-initializing fsmEvse") + self.state = 0 + self.cyclesInState = 0 + self.rxData = [] + def __init__(self): print("initializing fsmEvse") self.Tcp = pyPlcTcpSocket.pyPlcTcpServerSocket() diff --git a/fsmPev.py b/fsmPev.py new file mode 100644 index 0000000..7f317bd --- /dev/null +++ b/fsmPev.py @@ -0,0 +1,83 @@ +# State machine for the car +# +# + +#------------------------------------------------------------ + +import pyPlcTcpSocket +import time # for time.sleep() + +stateInitialized = 0 +stateWaitForSupportedApplicationProtocolResponse = 1 +stateWaitForSessionSetupResponse = 2 +stateWaitForServiceDiscoveryResponse = 3 +stateWaitForPaymentServiceSelectionResponse = 4 +stateWaitForAuthorizationResponse = 5 +stateWaitForChargeParameterResponse = 6 +stateWaitForCableCheckResponse = 7 +stateWaitForPreChargeResponse = 8 +stateWaitForPowerDeliveryResponse = 9 + +class fsmPev(): + def enterState(self, n): + print("from " + str(self.state) + " entering " + str(n)) + self.state = n + self.cyclesInState = 0 + + def isTooLong(self): + # The timeout handling function. + return (self.cyclesInState > 20) + + def stateFunctionInitialized(self): + if (self.Tcp.isConnected): + self.Tcp.transmit(bytes("TestFromPevInInitialized", "utf-8")) + self.enterState(stateWaitForSupportedApplicationProtocolResponse) + + def stateFunctionWaitForSupportedApplicationProtocolResponse(self): + if (len(self.rxData)>0): + pass + + stateFunctions = { + stateInitialized: stateFunctionInitialized, + stateWaitForSupportedApplicationProtocolResponse: stateFunctionWaitForSupportedApplicationProtocolResponse, + } + + def reInit(self): + print("re-initializing fsmPev") + self.state = stateInitialized + self.cyclesInState = 0 + self.rxData = [] + if (not self.Tcp.isConnected): + self.Tcp.connect('fe80::e0ad:99ac:52eb:85d3', 15118) + if (not self.Tcp.isConnected): + print("connection failed") + else: + print("connected") + + def __init__(self): + print("initializing fsmPev") + self.Tcp = pyPlcTcpSocket.pyPlcTcpClientSocket() + self.reInit() + + def mainfunction(self): + #self.Tcp.mainfunction() # call the lower-level worker + if (self.Tcp.isRxDataAvailable()): + self.rxData = self.Tcp.getRxData() + 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: + self.cyclesInState += 1 # for timeout handling, count how long we are in a state + self.stateFunctions[self.state](self) + + +if __name__ == "__main__": + print("Testing the pev state machine") + pev = fsmPev() + print("Press Ctrl-Break for aborting") + while (True): + time.sleep(0.1) + pev.mainfunction() + + diff --git a/pyPlc.py b/pyPlc.py index fb640b2..932ce63 100644 --- a/pyPlc.py +++ b/pyPlc.py @@ -9,6 +9,8 @@ import tkinter as tk import time import pyPlcWorker +from pyPlcModes import * +import sys # for argv def storekeyname(event): global nKeystrokes @@ -38,6 +40,21 @@ def cbShowStatus(s, selection=""): lblStatus['text']=s root.update() +myMode = C_LISTEN_MODE +if (len(sys.argv) > 1): + if (sys.argv[1] == "P"): + myMode = C_PEV_MODE + else: + if (sys.argv[1] == "E"): + myMode = C_EVSE_MODE + +if (myMode == C_LISTEN_MODE): + print("starting in LISTEN_MODE") +if (myMode == C_PEV_MODE): + print("starting in PEV_MODE") +if (myMode == C_EVSE_MODE): + print("starting in EVSE_MODE") + root = tk.Tk() lastKey = '' lblHelp = tk.Label(root, justify= "left") @@ -54,7 +71,7 @@ lblMode.pack() root.bind('', storekeyname) cbShowStatus("initialized") root.update() -worker=pyPlcWorker.pyPlcWorker(cbAddToTrace, cbShowStatus) +worker=pyPlcWorker.pyPlcWorker(cbAddToTrace, cbShowStatus, myMode) nMainloops=0 nKeystrokes=0 diff --git a/pyPlcHomeplug.py b/pyPlcHomeplug.py index 1da81a0..eb835f8 100644 --- a/pyPlcHomeplug.py +++ b/pyPlcHomeplug.py @@ -36,6 +36,7 @@ import pcap import pyPlcIpv6 from helpers import * # prettyMac etc +from pyPlcModes import * MAC_BROADCAST = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ] MAC_LAPTOP = [0xdc, 0x0e, 0xa1, 0x11, 0x67, 0x08 ] # Win10 laptop @@ -532,7 +533,7 @@ class pyPlcHomeplug(): if (strInterfaceName == '\\Device\\NPF_{E4B8176C-8516-4D48-88BC-85225ABCF259}'): print("This is the wanted Ethernet adaptor.") self.strInterfaceName="eth"+str(i) - print("eth"+ str(i) + " is " + strInterfaceName) + #print("eth"+ str(i) + " is " + strInterfaceName) def enterPevMode(self): self.iAmEvse = 0 # not emulating a charging station @@ -550,7 +551,7 @@ class pyPlcHomeplug(): self.ipv6.enterListenMode() self.showStatus("LISTEN mode", "mode") - def __init__(self, callbackAddToTrace=None, callbackShowStatus=None): + def __init__(self, callbackAddToTrace=None, callbackShowStatus=None, mode=C_LISTEN_MODE): self.mytransmitbuffer = bytearray("Hallo das ist ein Test", 'UTF-8') self.nPacketsReceived = 0 self.callbackAddToTrace = callbackAddToTrace @@ -580,7 +581,12 @@ class pyPlcHomeplug(): self.runningCounter=0 self.ipv6 = pyPlcIpv6.ipv6handler(self.transmit) self.ipv6.ownMac = self.myMAC - self.enterEvseMode() + if (mode == C_LISTEN_MODE): + self.enterListenMode() + if (mode == C_EVSE_MODE): + self.enterEvseMode() + if (mode == C_PEV_MODE): + self.enterPevMode() self.showStatus(prettyMac(self.pevMac), "pevmac") print("sniffer created at " + self.strInterfaceName) diff --git a/pyPlcModes.py b/pyPlcModes.py new file mode 100644 index 0000000..b7f8e9d --- /dev/null +++ b/pyPlcModes.py @@ -0,0 +1,5 @@ + + +C_LISTEN_MODE = 0 # listen to the communication. No active participation. +C_EVSE_MODE = 1 # play the role of the charger +C_PEV_MODE = 2 # play the role of the car diff --git a/pyPlcTcpSocket.py b/pyPlcTcpSocket.py index edf7ef1..139d2ac 100644 --- a/pyPlcTcpSocket.py +++ b/pyPlcTcpSocket.py @@ -14,7 +14,7 @@ import sys # for argv import time # for time.sleep() import errno -class pyPlcClientSocket(): +class pyPlcTcpClientSocket(): def __init__(self): self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) self.isConnected = False @@ -189,7 +189,7 @@ def testServerSocket(): def testClientSocket(): print("Testing the pyPlcTcpClientSocket...") - c = pyPlcClientSocket() + c = pyPlcTcpClientSocket() c.connect('fe80::e0ad:99ac:52eb:85d3', 15118) print("connected="+str(c.isConnected)) print("sending something to the server") diff --git a/pyPlcWorker.py b/pyPlcWorker.py index 3b72b6d..a68eb03 100644 --- a/pyPlcWorker.py +++ b/pyPlcWorker.py @@ -5,15 +5,23 @@ #------------------------------------------------------------ import pyPlcHomeplug +import fsmEvse +import fsmPev +from pyPlcModes import * class pyPlcWorker(): - def __init__(self, callbackAddToTrace=None, callbackShowStatus=None): + def __init__(self, callbackAddToTrace=None, callbackShowStatus=None, mode=C_EVSE_MODE): print("initializing pyPlcWorker") self.nMainFunctionCalls=0 + self.mode = mode self.strUserAction = "" self.callbackAddToTrace = callbackAddToTrace self.callbackShowStatus = callbackShowStatus - self.hp = pyPlcHomeplug.pyPlcHomeplug(self.callbackAddToTrace, self.callbackShowStatus) + self.hp = pyPlcHomeplug.pyPlcHomeplug(self.callbackAddToTrace, self.callbackShowStatus, self.mode) + if (self.mode == C_EVSE_MODE): + self.evse = fsmEvse.fsmEvse() + if (self.mode == C_PEV_MODE): + self.pev = fsmPev.fsmPev() def addToTrace(self, s): self.callbackAddToTrace(s) @@ -25,15 +33,45 @@ class pyPlcWorker(): self.nMainFunctionCalls+=1 #self.showStatus("pyPlcWorker loop " + str(self.nMainFunctionCalls)) self.hp.mainfunction() # call the lower-level worker + if (self.mode == C_EVSE_MODE): + self.evse.mainfunction() # call the evse state machine + if (self.mode == C_PEV_MODE): + self.pev.mainfunction() # call the pev state machine def handleUserAction(self, strAction): self.strUserAction = strAction if (strAction == "P"): + print("switching to PEV mode") + self.mode = C_PEV_MODE + if (hasattr(self, 'evse')): + print("deleting evse") + del self.evse self.hp.enterPevMode() + if (not hasattr(self, 'pev')): + print("creating pev") + self.pev = fsmPev.fsmPev() + self.pev.reInit() if (strAction == "E"): + print("switching to EVSE mode") + self.mode = C_EVSE_MODE + if (hasattr(self, 'pev')): + print("deleting pev") + del self.pev self.hp.enterEvseMode() + if (not hasattr(self, 'evse')): + print("creating fsmEvse") + self.evse = fsmEvse.fsmEvse() + self.evse.reInit() if (strAction == "L"): + print("switching to LISTEN mode") + self.mode = C_LISTEN_MODE self.hp.enterListenMode() + if (hasattr(self, 'evse')): + print("deleting evse") + del self.evse + if (hasattr(self, 'pev')): + print("deleting pev") + del self.pev # self.addToTrace("UserAction " + strAction) self.hp.sendTestFrame(strAction)