mirror of
https://github.com/uhi22/pyPLC.git
synced 2024-11-10 01:05:42 +00:00
feature: in EvseMode, control the power supply via special homeplug message
This commit is contained in:
parent
7e86812032
commit
a5991434e1
4 changed files with 66 additions and 5 deletions
|
@ -263,6 +263,8 @@ class fsmEvse():
|
||||||
if (self.simulatedPresentVoltage<uTarget):
|
if (self.simulatedPresentVoltage<uTarget):
|
||||||
self.simulatedPresentVoltage += 5
|
self.simulatedPresentVoltage += 5
|
||||||
strPresentVoltage = str(self.simulatedPresentVoltage) # "345"
|
strPresentVoltage = str(self.simulatedPresentVoltage) # "345"
|
||||||
|
# in case we control a real power supply: give the precharge target to it
|
||||||
|
self.hardwareInterface.setPowerSupplyVoltageAndCurrent(uTarget, 1)
|
||||||
self.callbackShowStatus(strPresentVoltage, "EVSEPresentVoltage")
|
self.callbackShowStatus(strPresentVoltage, "EVSEPresentVoltage")
|
||||||
msg = addV2GTPHeader(exiEncode("E"+self.schemaSelection+"g_"+strPresentVoltage)) # EDg for Encode, Din, PreChargeResponse
|
msg = addV2GTPHeader(exiEncode("E"+self.schemaSelection+"g_"+strPresentVoltage)) # EDg for Encode, Din, PreChargeResponse
|
||||||
if (testsuite_faultinjection_is_triggered(TC_EVSE_Shutdown_during_PreCharge)):
|
if (testsuite_faultinjection_is_triggered(TC_EVSE_Shutdown_during_PreCharge)):
|
||||||
|
@ -434,7 +436,7 @@ class fsmEvse():
|
||||||
self.callbackShowStatus = callbackShowStatus
|
self.callbackShowStatus = callbackShowStatus
|
||||||
self.callbackSoCStatus = callbackSoCStatus
|
self.callbackSoCStatus = callbackSoCStatus
|
||||||
#todo self.addressManager = addressManager
|
#todo self.addressManager = addressManager
|
||||||
#todo self.hardwareInterface = hardwareInterface
|
self.hardwareInterface = hardwareInterface
|
||||||
self.addToTrace("initializing fsmEvse")
|
self.addToTrace("initializing fsmEvse")
|
||||||
self.faultInjectionDelayUntilSocketOpen_s = 0
|
self.faultInjectionDelayUntilSocketOpen_s = 0
|
||||||
if (self.faultInjectionDelayUntilSocketOpen_s>0):
|
if (self.faultInjectionDelayUntilSocketOpen_s>0):
|
||||||
|
|
|
@ -156,6 +156,10 @@ class hardwareInterface():
|
||||||
self.chargerVoltage = int(voltageNow)
|
self.chargerVoltage = int(voltageNow)
|
||||||
self.chargerCurrent = int(currentNow)
|
self.chargerCurrent = int(currentNow)
|
||||||
|
|
||||||
|
def setPowerSupplyVoltageAndCurrent(self, targetVoltage, targetCurrent):
|
||||||
|
# if we are the charger, and have a real power supply which we want to control, we do it here
|
||||||
|
self.homeplughandler.sendSpecialMessageToControlThePowerSupply(targetVoltage, targetCurrent)
|
||||||
|
|
||||||
def getInletVoltage(self):
|
def getInletVoltage(self):
|
||||||
# uncomment this line, to take the simulated inlet voltage instead of the really measured
|
# uncomment this line, to take the simulated inlet voltage instead of the really measured
|
||||||
# self.inletVoltage = self.simulatedInletVoltage
|
# self.inletVoltage = self.simulatedInletVoltage
|
||||||
|
@ -224,9 +228,10 @@ class hardwareInterface():
|
||||||
GPIO.setup(PinPowerRelay, GPIO.OUT) #output for port relays
|
GPIO.setup(PinPowerRelay, GPIO.OUT) #output for port relays
|
||||||
GPIO.setup(PinCp, GPIO.OUT) #output for CP
|
GPIO.setup(PinCp, GPIO.OUT) #output for CP
|
||||||
|
|
||||||
def __init__(self, callbackAddToTrace=None, callbackShowStatus=None):
|
def __init__(self, callbackAddToTrace=None, callbackShowStatus=None, homeplughandler=None):
|
||||||
self.callbackAddToTrace = callbackAddToTrace
|
self.callbackAddToTrace = callbackAddToTrace
|
||||||
self.callbackShowStatus = callbackShowStatus
|
self.callbackShowStatus = callbackShowStatus
|
||||||
|
self.homeplughandler = homeplughandler
|
||||||
|
|
||||||
self.loopcounter = 0
|
self.loopcounter = 0
|
||||||
self.outvalue = 0
|
self.outvalue = 0
|
||||||
|
|
|
@ -358,6 +358,37 @@ class pyPlcHomeplug():
|
||||||
self.fillRunId(36) # 36 to 43 runid 8 bytes
|
self.fillRunId(36) # 36 to 43 runid 8 bytes
|
||||||
# rest is 00
|
# rest is 00
|
||||||
|
|
||||||
|
def composeSpecialMessage(self):
|
||||||
|
# special "homeplug" message, to control a hardware device.
|
||||||
|
# We re-purpose the ATTEN_CHAR.IND, because a AR4720 PEV modem is transparent for it also in unpaired state,
|
||||||
|
# and it contains a lot of space which can be used to transfer data. Also it is not expected to disturb the
|
||||||
|
# normal traffic, because it may be also caused by cross-coupling from an other charger, and the normal
|
||||||
|
# communication should be immune to such things.
|
||||||
|
self.mytransmitbuffer = bytearray(129)
|
||||||
|
self.cleanTransmitBuffer()
|
||||||
|
# Destination MAC
|
||||||
|
self.fillDestinationMac(MAC_BROADCAST)
|
||||||
|
# Source MAC
|
||||||
|
self.fillSourceMac(self.myMAC)
|
||||||
|
# Protocol
|
||||||
|
self.mytransmitbuffer[12]=0x88 # Protocol HomeplugAV
|
||||||
|
self.mytransmitbuffer[13]=0xE1
|
||||||
|
self.mytransmitbuffer[14]=0x01 # version
|
||||||
|
self.mytransmitbuffer[15]=0x6E # ATTEN_CHAR.IND
|
||||||
|
self.mytransmitbuffer[16]=0x60 #
|
||||||
|
self.mytransmitbuffer[17]=0x00 # 2 bytes fragmentation information. 0000 means: unfragmented.
|
||||||
|
self.mytransmitbuffer[18]=0x00 #
|
||||||
|
self.mytransmitbuffer[19]=0x00 # apptype
|
||||||
|
self.mytransmitbuffer[20]=0x00 # security
|
||||||
|
self.fillDestinationMac(MAC_BROADCAST, 21) # The wireshark calls it source_mac, but alpitronic fills it with PEV mac.
|
||||||
|
self.fillRunId(27) # runid 8 bytes
|
||||||
|
self.mytransmitbuffer[35]=0x00 # 35 - 51 source_id, 17 bytes. The alpitronic fills it with 00
|
||||||
|
self.mytransmitbuffer[52]=0x00 # 52 - 68 response_id, 17 bytes. The alpitronic fills it with 00.
|
||||||
|
self.mytransmitbuffer[69]=0x0A # Number of sounds. 10 in normal case.
|
||||||
|
self.mytransmitbuffer[70]=0x3A # Number of groups = 58.
|
||||||
|
for i in range(71, 129): # 71 to 128: 58 special-purpose-bytes
|
||||||
|
self.mytransmitbuffer[i]=self.specialMessageTransmitBuffer[i-71]
|
||||||
|
|
||||||
def composeStartAttenCharInd(self):
|
def composeStartAttenCharInd(self):
|
||||||
# reference: see wireshark interpreted frame from ioniq
|
# reference: see wireshark interpreted frame from ioniq
|
||||||
self.mytransmitbuffer = bytearray(60)
|
self.mytransmitbuffer = bytearray(60)
|
||||||
|
@ -555,6 +586,10 @@ class pyPlcHomeplug():
|
||||||
self.composeGetSwWithRamdomMac()
|
self.composeGetSwWithRamdomMac()
|
||||||
self.addToTrace("transmitting GetSwWithRamdomMac")
|
self.addToTrace("transmitting GetSwWithRamdomMac")
|
||||||
self.transmit(self.mytransmitbuffer)
|
self.transmit(self.mytransmitbuffer)
|
||||||
|
if (selection=="9"):
|
||||||
|
self.composeSpecialMessage()
|
||||||
|
self.addToTrace("transmitting SpecialMessage")
|
||||||
|
self.transmit(self.mytransmitbuffer)
|
||||||
|
|
||||||
def transmit(self, pkt):
|
def transmit(self, pkt):
|
||||||
self.sniffer.sendpacket(bytes(pkt))
|
self.sniffer.sendpacket(bytes(pkt))
|
||||||
|
@ -1069,6 +1104,24 @@ class pyPlcHomeplug():
|
||||||
self.strInterfaceName=getConfigValue("eth_interface")
|
self.strInterfaceName=getConfigValue("eth_interface")
|
||||||
print("Linux interface is " + self.strInterfaceName)
|
print("Linux interface is " + self.strInterfaceName)
|
||||||
|
|
||||||
|
def sendSpecialMessageToControlThePowerSupply(self, targetVoltage, targetCurrent):
|
||||||
|
u = int(targetVoltage*10) # resolution: 0.1 volt
|
||||||
|
i = int(targetCurrent*10) # resolution: 0.1 ampere
|
||||||
|
self.specialMessageTransmitBuffer[0] = 0xAF # Header 3 byte
|
||||||
|
self.specialMessageTransmitBuffer[1] = 0xFE #
|
||||||
|
self.specialMessageTransmitBuffer[2] = 0xDC #
|
||||||
|
self.specialMessageTransmitBuffer[3] = u >> 8 # target voltage, MSB first
|
||||||
|
self.specialMessageTransmitBuffer[4] = u & 0xFF # target voltage, LSB
|
||||||
|
self.specialMessageTransmitBuffer[5] = u >> 8 # same again, for plausibilization
|
||||||
|
self.specialMessageTransmitBuffer[6] = u & 0xFF
|
||||||
|
self.specialMessageTransmitBuffer[7] = i >> 8 # target current, MSB first
|
||||||
|
self.specialMessageTransmitBuffer[8] = i & 0xFF # target current, LSB
|
||||||
|
self.specialMessageTransmitBuffer[9] = i >> 8 # same again
|
||||||
|
self.specialMessageTransmitBuffer[10] = i & 0xFF
|
||||||
|
self.composeSpecialMessage()
|
||||||
|
self.addToTrace("transmitting SpecialMessage to control the power supply")
|
||||||
|
self.transmit(self.mytransmitbuffer)
|
||||||
|
|
||||||
def enterPevMode(self):
|
def enterPevMode(self):
|
||||||
self.iAmEvse = 0 # not emulating a charging station
|
self.iAmEvse = 0 # not emulating a charging station
|
||||||
self.iAmPev = 1 # emulating a vehicle
|
self.iAmPev = 1 # emulating a vehicle
|
||||||
|
@ -1134,6 +1187,7 @@ class pyPlcHomeplug():
|
||||||
# a default pev RunId. Will be overwritten later, if we are evse. If we are the pev, we are free to choose a
|
# a default pev RunId. Will be overwritten later, if we are evse. If we are the pev, we are free to choose a
|
||||||
# RunID, e.g. the Ioniq uses the MAC plus 0x00 0x00 padding, the Tesla uses "TESLA EV".
|
# RunID, e.g. the Ioniq uses the MAC plus 0x00 0x00 padding, the Tesla uses "TESLA EV".
|
||||||
self.pevRunId = [0xDC, 0x0E, 0xA1, 0xDE, 0xAD, 0xBE, 0xEF, 0x55 ]
|
self.pevRunId = [0xDC, 0x0E, 0xA1, 0xDE, 0xAD, 0xBE, 0xEF, 0x55 ]
|
||||||
|
self.specialMessageTransmitBuffer = bytearray(58)
|
||||||
self.myMAC = self.addressManager.getLocalMacAddress()
|
self.myMAC = self.addressManager.getLocalMacAddress()
|
||||||
self.runningCounter=0
|
self.runningCounter=0
|
||||||
self.ipv6 = pyPlcIpv6.ipv6handler(self.transmit, self.addressManager, self.connMgr, self.callbackShowStatus)
|
self.ipv6 = pyPlcIpv6.ipv6handler(self.transmit, self.addressManager, self.connMgr, self.callbackShowStatus)
|
||||||
|
|
|
@ -31,7 +31,7 @@ class pyPlcWorker():
|
||||||
self.isSimulationMode = isSimulationMode
|
self.isSimulationMode = isSimulationMode
|
||||||
self.connMgr = connMgr.connMgr(self.workerAddToTrace, self.showStatus)
|
self.connMgr = connMgr.connMgr(self.workerAddToTrace, self.showStatus)
|
||||||
self.hp = pyPlcHomeplug.pyPlcHomeplug(self.workerAddToTrace, self.showStatus, self.mode, self.addressManager, self.connMgr, self.isSimulationMode)
|
self.hp = pyPlcHomeplug.pyPlcHomeplug(self.workerAddToTrace, self.showStatus, self.mode, self.addressManager, self.connMgr, self.isSimulationMode)
|
||||||
self.hardwareInterface = hardwareInterface.hardwareInterface(self.workerAddToTrace, self.showStatus)
|
self.hardwareInterface = hardwareInterface.hardwareInterface(self.workerAddToTrace, self.showStatus, self.hp)
|
||||||
self.hp.printToUdp("pyPlcWorker init")
|
self.hp.printToUdp("pyPlcWorker init")
|
||||||
# Find out the version number, using git.
|
# Find out the version number, using git.
|
||||||
# see https://stackoverflow.com/questions/14989858/get-the-current-git-hash-in-a-python-script
|
# see https://stackoverflow.com/questions/14989858/get-the-current-git-hash-in-a-python-script
|
||||||
|
|
Loading…
Reference in a new issue