diff --git a/exiConnector.py b/exiConnector.py index 57ee72b..46be452 100644 --- a/exiConnector.py +++ b/exiConnector.py @@ -294,7 +294,7 @@ if __name__ == "__main__": if (False): testTimeConsumption() exit() - if (False): + if (True): testReadExiFromExiLogFile() exit() @@ -318,7 +318,7 @@ if __name__ == "__main__": if (False): print("The request from the Ioniq after the EVSE sent ServicePaymentSelectionRes:") testDecoder("809A00113020000A00000000", pre="DD", comment="PowerDeliveryReq") - if (True): + if (False): #print("The session setup request of the Ioniq:") #testDecoder("809A02000000000000000011D01811959401930C00", pre="DD", comment="SessionSetupReq") print("Ioniq with pyPlc") @@ -329,7 +329,7 @@ if __name__ == "__main__": #testDecoder("809a02004080c1014181c2116002000000320000", pre="DD") # 2022-11-11, 27.659s PrechargeRes #print("A ChargeParameterDiscoveryReq") #testDecoder("809a00107211400dc0c8c82324701900", pre="DD", comment="ChargeParameterDiscoveryReq") - if (True): + if (False): print("From https://openinverter.org/forum/viewtopic.php?p=54692#p54692") testDecoder("809A0233EBC74AB099A6DC907191400500C8C82324701900", pre="DD") # from https://openinverter.org/forum/viewtopic.php?p=54692#p54692 diff --git a/fsmPev.py b/fsmPev.py index 83aa0cc..95665fd 100644 --- a/fsmPev.py +++ b/fsmPev.py @@ -7,7 +7,7 @@ import pyPlcTcpSocket import time # for time.sleep() from datetime import datetime -from helpers import prettyHexMessage, compactHexMessage +from helpers import prettyHexMessage, compactHexMessage, combineValueAndMultiplier from exiConnector import * # for EXI data handling/converting import json @@ -345,12 +345,26 @@ class fsmPev(): strConverterResult = self.exiDecode(exidata, "DD") # Decode DIN self.addToTrace(strConverterResult) if (strConverterResult.find("PreChargeRes")>0): - # todo: check the request content, and fill response parameters - self.addToTrace("PreCharge aknowledge received.") - s = "U_Inlet " + str(self.hardwareInterface.getInletVoltage()) + "V, " + u = 0 # a default voltage of 0V in case we cannot convert the actual value + try: + y = json.loads(strConverterResult) + strEVSEPresentVoltageValue = y["EVSEPresentVoltage.Value"] + strEVSEPresentVoltageMultiplier = y["EVSEPresentVoltage.Multiplier"] + u = combineValueAndMultiplier(strEVSEPresentVoltageValue, strEVSEPresentVoltageMultiplier) + self.callbackShowStatus(format(u,".1f"), "EVSEPresentVoltage") + except: + self.addToTrace("ERROR: Could not decode the PreChargeResponse") + self.addToTrace("PreChargeResponse received.") + if (self.USE_EVSEPRESENTVOLTAGE_FOR_PRECHARGE_END): + # We want to use the EVSEPresentVoltage, which was reported by the charger, as end-criteria for the precharging. + s = "EVSEPresentVoltage " + str(u) + "V, " + else: + # We want to use the physically measured inlet voltage as end-criteria for the precharging. + u = self.hardwareInterface.getInletVoltage() + s = "U_Inlet " + str(u) + "V, " s= s + "U_Accu " + str(self.hardwareInterface.getAccuVoltage()) + "V" self.addToTrace(s) - if (abs(self.hardwareInterface.getInletVoltage()-self.hardwareInterface.getAccuVoltage()) < PARAM_U_DELTA_MAX_FOR_END_OF_PRECHARGE): + if (abs(u-self.hardwareInterface.getAccuVoltage()) < PARAM_U_DELTA_MAX_FOR_END_OF_PRECHARGE): self.addToTrace("Difference between accu voltage and inlet voltage is small. Sending PowerDeliveryReq.") self.publishStatus("PreCharge done") if (self.isLightBulbDemo): @@ -366,7 +380,7 @@ class fsmPev(): self.Tcp.transmit(msg) self.enterState(stateWaitForPowerDeliveryResponse) else: - self.publishStatus("PreChrge ongoing", format(self.hardwareInterface.getInletVoltage(), ".0f") + "V") + self.publishStatus("PreChrge ongoing", format(u, ".0f") + "V") self.addToTrace("Difference too big. Continuing PreCharge.") soc = self.hardwareInterface.getSoc() EVTargetVoltage = self.hardwareInterface.getAccuVoltage() @@ -410,6 +424,18 @@ class fsmPev(): strConverterResult = self.exiDecode(exidata, "DD") # Decode DIN self.addToTrace(strConverterResult) if (strConverterResult.find("CurrentDemandRes")>0): + u = 0 # a default voltage of 0V in case we cannot convert the actual value + try: + y = json.loads(strConverterResult) + strEVSEPresentVoltageValue = y["EVSEPresentVoltage.Value"] + strEVSEPresentVoltageMultiplier = y["EVSEPresentVoltage.Multiplier"] + u = combineValueAndMultiplier(strEVSEPresentVoltageValue, strEVSEPresentVoltageMultiplier) + self.callbackShowStatus(format(u,".1f"), "EVSEPresentVoltage") + except: + self.addToTrace("ERROR: Could not decode the PreChargeResponse") + if (self.USE_PHYSICAL_INLET_VOLTAGE_DURING_CHARGELOOP): + # Instead of using the voltage which is reported by the charger, use the physically measured. + u = self.hardwareInterface.getInletVoltage() # as long as the accu is not full and no stop-demand from the user, we continue charging if (self.hardwareInterface.getIsAccuFull() or self.isUserStopRequest): if (self.hardwareInterface.getIsAccuFull()): @@ -426,7 +452,7 @@ class fsmPev(): self.enterState(stateWaitForPowerDeliveryResponse) else: # continue charging loop - self.publishStatus("Charging", format(self.hardwareInterface.getInletVoltage(), ".0f") + "V", format(self.hardwareInterface.getSoc(), ".1f") + "%") + self.publishStatus("Charging", format(u, ".0f") + "V", format(self.hardwareInterface.getSoc(), ".1f") + "%") self.sendCurrentDemandReq() self.enterState(stateWaitForCurrentDemandResponse) if (self.isLightBulbDemo): @@ -546,6 +572,10 @@ class fsmPev(): self.isBulbOn = False self.cyclesLightBulbDelay = 0 self.isUserStopRequest = False + self.USE_EVSEPRESENTVOLTAGE_FOR_PRECHARGE_END = 1 # to configure, which criteria is used for end of PreCharge + self.USE_PHYSICAL_INLET_VOLTAGE_DURING_CHARGELOOP = 0 # to configure, whether to display the measured or charger-reported + # voltage during the charging loop + # we do NOT call the reInit, because we want to wait with the connection until external trigger comes def __del__(self): diff --git a/helpers.py b/helpers.py index 5ef69e5..74f4bde 100644 --- a/helpers.py +++ b/helpers.py @@ -33,4 +33,20 @@ def prettyMac(macByteArray): for i in range(0, length-1): s = s + twoCharHex(macByteArray[i]) + ":" s = s + twoCharHex(macByteArray[length-1]) - return s \ No newline at end of file + return s + +def combineValueAndMultiplier(value, mult): + # input: value and multipliers as strings + # output: The numerical value x* 10^mult + x = float(value) + m = int(mult) + return x * 10**m + +if __name__ == "__main__": + print("Testing the helpers") + print(str(combineValueAndMultiplier("123", "0")) + " should be 123") + print(str(combineValueAndMultiplier("5678", "-1")) + " should be 567.8") + print(str(combineValueAndMultiplier("-17", "1")) + " should be -170") + print(str(combineValueAndMultiplier("4", "4")) + " should be 40000") + + \ No newline at end of file diff --git a/pyPlc.py b/pyPlc.py index 88eacc4..7a55b0e 100644 --- a/pyPlc.py +++ b/pyPlc.py @@ -39,6 +39,9 @@ def cbShowStatus(s, selection=""): if (selection == "uInlet"): lblUInlet['text']= "UInlet " + s + "V" s="" + if (selection == "EVSEPresentVoltage"): + lblEVSEPresentVoltage['text']= "EVSEPresentVoltage " + s + "V" + s="" if (selection == "pevState"): lblState['text']= s s="" @@ -73,7 +76,7 @@ if (myMode == C_EVSE_MODE): print("starting in EVSE_MODE") root = tk.Tk() -root.geometry("400x300") +root.geometry("400x350") lastKey = '' lblHelp = tk.Label(root, justify= "left") lblHelp['text']="x=exit \nS=GET_SW \nP=PEV mode \nE=EVSE mode \nL=Listen mode \ns=SET_KEY \nG=GET_KEY (try twice) \nt=SET_KEY modified \n space=stop charging" @@ -90,6 +93,9 @@ lblSoc.pack() lblUInlet = tk.Label(root, text="(U Inlet)") lblUInlet.config(font=('Helvetica bold', 26)) lblUInlet.pack() +lblEVSEPresentVoltage = tk.Label(root, text="(EVSEPresentVoltage)") +lblEVSEPresentVoltage.config(font=('Helvetica bold', 16)) +lblEVSEPresentVoltage.pack() lblMode = tk.Label(root, text="(mode)") lblMode.pack()