From 219ca7f51dc1a5c4798189386780139ccc73a435 Mon Sep 17 00:00:00 2001 From: Demo User Date: Tue, 20 Jun 2023 10:43:03 +0000 Subject: [PATCH 1/7] added CHAdeMO backend --- doc/pyPlc.ini.template | 4 +++ hardwareInterface.py | 62 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/doc/pyPlc.ini.template b/doc/pyPlc.ini.template index 8a6d71d..3ef1945 100644 --- a/doc/pyPlc.ini.template +++ b/doc/pyPlc.ini.template @@ -99,6 +99,10 @@ testsuite_enable = No # in form of UDP Syslog messages. For details see in udplog.py. udp_syslog_enable = Yes +# Set backend for obtaining charging parameters, we start with CHAdeMO CAN for now +# Need to make a simulator device and maybe a celeron device? +charge_parameter_backend = chademo + # REST callback for SoC states. Comment out to disable. Do not leave a trailing slash soc_callback_enabled = False soc_callback_endpoint = http://1.1.1.1 diff --git a/hardwareInterface.py b/hardwareInterface.py index 0263437..7502575 100644 --- a/hardwareInterface.py +++ b/hardwareInterface.py @@ -16,6 +16,10 @@ if (getConfigValue("digital_output_device")=="beaglebone"): # In case we run on beaglebone, we want to use GPIO ports. import Adafruit_BBIO.GPIO as GPIO +if (getConfigValue("charge_parameter_backend")=="chademo"): + # In case we run on beaglebone, we want to use GPIO ports. + import can + class hardwareInterface(): def needsSerial(self): # Find out, whether we need a serial port. This depends on several configuration items. @@ -149,6 +153,8 @@ class hardwareInterface(): def getAccuVoltage(self): if (getConfigValue("digital_output_device")=="celeron55device"): return self.accuVoltage + elif getConfigValue("charge_parameter_backend")=="chademo": + return self.accuVoltage #todo: get real measured voltage from the accu self.accuVoltage = 230 return self.accuVoltage @@ -161,13 +167,17 @@ class hardwareInterface(): if self.accuMaxCurrent >= EVMaximumCurrentLimit: return EVMaximumCurrentLimit return self.accuMaxCurrent + elif getConfigValue("charge_parameter_backend")=="chademo": + return self.accuMaxCurrent #set by CAN #todo: get max charging current from the BMS self.accuMaxCurrent = 10 return self.accuMaxCurrent def getAccuMaxVoltage(self): if getConfigValue("charge_target_voltage"): - self.accuMaxVoltage = getConfigValue("charge_target_voltage") + self.accuMaxVoltage = getConfigValue("charge_target_voltage") + elif getConfigValue("charge_parameter_backend")=="chademo": + return self.accuMaxVoltage #set by CAN else: #todo: get max charging voltage from the BMS self.accuMaxVoltage = 230 @@ -191,6 +201,13 @@ class hardwareInterface(): return self.simulatedSoc def initPorts(self): + if (getConfigValue("charge_parameter_backend") == "chademo"): + filters = [ + {"can_id": 0x100, "can_mask": 0x7FF, "extended": False}, + {"can_id": 0x101, "can_mask": 0x7FF, "extended": False}, + {"can_id": 0x102, "can_mask": 0x7FF, "extended": False}] + self.canbus = can.interface.Bus(bustype='socketcan', channel="can0", can_filters = filters) + if (getConfigValue("digital_output_device") == "beaglebone"): # Port configuration according to https://github.com/jsphuebner/pyPLC/commit/475f7fe9f3a67da3d4bd9e6e16dfb668d0ddb1d6 GPIO.setup("P8_16", GPIO.OUT) #output for port relays @@ -209,6 +226,8 @@ class hardwareInterface(): self.lock_confirmed = False # Confirmation from hardware self.cp_pwm = 0.0 self.soc_percent = 0.0 + self.capacity = 0.0 + self.accuMaxVoltage = 0.0 self.accuMaxCurrent = 0.0 self.contactor_confirmed = False # Confirmation from hardware self.plugged_in = None # None means "not known yet" @@ -336,6 +355,9 @@ class hardwareInterface(): # 0.5 charging needs ~8s, good for automatic test case runs. self.simulatedSoc = self.simulatedSoc + deltaSoc + if (getConfigValue("charge_parameter_backend")=="chademo"): + self.mainfunction_chademo() + if (getConfigValue("digital_output_device")=="dieter"): self.mainfunction_dieter() @@ -376,6 +398,44 @@ class hardwareInterface(): s = "" # for the case we received corrupted data (not convertable as utf-8) #self.addToTrace(str(len(s)) + " bytes received: " + s) self.evaluateReceivedData_celeron55device(s) + + def mainfunction_chademo(self): + message = self.canbus.recv(0) + + if message: + if message.arbitration_id == 0x100: + vtg = (message.data[1] << 8) + message.data[0] + if self.accuVoltage != vtg: + self.addToTrace("CHAdeMO: Set battery voltage to %d V" % vtg) + self.accuVoltage = vtg + if self.capacity != message.data[6]: + self.addToTrace("CHAdeMO: Set capacity to %d" % message.data[6]) + self.capacity = message.data[6] + + #TODO: determine maximum charger current and voltage and also actual current and voltage + msg = can.Message(arbitration_id=0x108, data=[ 0, 0, 0, 125, 0, 0, 0, 0], is_extended_id=False) + self.canbus.send(msg) + #Report unspecified version 10, this makes our custom implementation send the + #battery voltage in 0x100 bytes 0 and 1 + status = 4 #report connector locked + msg = can.Message(arbitration_id=0x109, data=[ 10, 0, 0, 0, 0, 0, 0, 0], is_extended_id=False) + self.canbus.send(msg) + + if message.arbitration_id == 0x102: + vtg = (message.data[2] << 8) + message.data[1] + if self.accuMaxVoltage != vtg: + self.addToTrace("CHAdeMO: Set target voltage to %d V" % vtg) + self.accuMaxVoltage = vtg + + if self.accuMaxCurrent != message.data[3]: + self.addToTrace("CHAdeMO: Set current request to %d A" % message.data[3]) + self.accuMaxCurrent = message.data[3] + + if self.capacity > 0: + soc = message.data[6] / self.capacity * 100 + if self.simulatedSoc != soc: + self.addToTrace("CHAdeMO: Set SoC to %d %%" % soc) + self.simulatedSoc = soc def myPrintfunction(s): print("myprint " + s) From 9286c539f0a3207e27f8641aac1f886c4f819542 Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 20 Jun 2023 14:12:21 +0200 Subject: [PATCH 2/7] Report charger parameters and momentary values to hardwareInterface --- fsmPev.py | 3 +++ hardwareInterface.py | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/fsmPev.py b/fsmPev.py index e1da261..95b3558 100644 --- a/fsmPev.py +++ b/fsmPev.py @@ -425,6 +425,8 @@ class fsmPev(): if (strConverterResult.find('"EVSEProcessing": "Finished"')>0): self.publishStatus("ChargeParams discovered") self.addToTrace("Checkpoint550: ChargeParams are discovered. Will change to state C.") + #Report charger paramters + self.hardwareInterface.setChargerParameters(500, 50) #TODO: send real parameters # pull the CP line to state C here: self.hardwareInterface.setStateC() self.addToTrace("Checkpoint555: Locking the connector.") @@ -653,6 +655,7 @@ class fsmPev(): u = combineValueAndMultiplier(strEVSEPresentVoltageValue, strEVSEPresentVoltageMultiplier) self.callbackShowStatus(format(u,".1f"), "EVSEPresentVoltage") strEVSEStatusCode = y["DC_EVSEStatus.EVSEStatusCode"] + self.hardwareInterface.setChargerVoltageAndCurrent(u, EVTargetCurrent) #TODO: report real current! except: self.addToTrace("ERROR: Could not decode the PreChargeResponse") if (strResponseCode!="OK"): diff --git a/hardwareInterface.py b/hardwareInterface.py index 7502575..acf7348 100644 --- a/hardwareInterface.py +++ b/hardwareInterface.py @@ -144,6 +144,14 @@ class hardwareInterface(): #if (getConfigValue("digital_output_device")=="celeron55device"): # return self.lock_confirmed return 1 # todo: use the real connector lock feedback + + def setChargerParameters(self, maxVoltage, maxCurrent): + self.maxChargerVoltage = int(maxVoltage) + self.maxChargerCurrent = int(maxCurrent) + + def setChargerVoltageAndCurrent(self, voltageNow, currentNow): + self.chargerVoltage = int(voltageNow) + self.chargerCurrent = int(currentNow) def getInletVoltage(self): # uncomment this line, to take the simulated inlet voltage instead of the really measured @@ -232,6 +240,11 @@ class hardwareInterface(): self.contactor_confirmed = False # Confirmation from hardware self.plugged_in = None # None means "not known yet" + self.maxChargerVoltage = 500 + self.maxChargerCurrent = 10 + self.chargerVoltage = 0 + self.chargerCurrent = 0 + self.logged_inlet_voltage = None self.logged_dc_link_voltage = None self.logged_cp_pwm = None @@ -413,12 +426,12 @@ class hardwareInterface(): self.capacity = message.data[6] #TODO: determine maximum charger current and voltage and also actual current and voltage - msg = can.Message(arbitration_id=0x108, data=[ 0, 0, 0, 125, 0, 0, 0, 0], is_extended_id=False) + msg = can.Message(arbitration_id=0x108, data=[ 0, self.maxChargerVoltage & 0xFF, self.maxChargerVoltage >> 8, self.maxChargerCurrent, 0, 0, 0, 0], is_extended_id=False) self.canbus.send(msg) - #Report unspecified version 10, this makes our custom implementation send the + #Report unspecified version 10, this makes our custom implementation send the momentary #battery voltage in 0x100 bytes 0 and 1 status = 4 #report connector locked - msg = can.Message(arbitration_id=0x109, data=[ 10, 0, 0, 0, 0, 0, 0, 0], is_extended_id=False) + msg = can.Message(arbitration_id=0x109, data=[ 10, self.chargerVoltage & 0xFF, self.chargerVoltage >> 8, self.chargerCurrent, 0, status, 0, 0], is_extended_id=False) self.canbus.send(msg) if message.arbitration_id == 0x102: From d88281a38637d3798b2898c047070a4803253082 Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 20 Jun 2023 14:12:31 +0200 Subject: [PATCH 3/7] Ignore .pyc files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3ec7c0c..456143e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ testresults.txt /log /local *.bak +*.pyc + From 2e75580fea1b7502764c87ae266a2cb9f81ea573 Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 20 Jun 2023 22:44:49 +0200 Subject: [PATCH 4/7] Sending real charger parameters and values to hardwareInterface --- fsmPev.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fsmPev.py b/fsmPev.py index 95b3558..61acb26 100644 --- a/fsmPev.py +++ b/fsmPev.py @@ -426,7 +426,9 @@ class fsmPev(): self.publishStatus("ChargeParams discovered") self.addToTrace("Checkpoint550: ChargeParams are discovered. Will change to state C.") #Report charger paramters - self.hardwareInterface.setChargerParameters(500, 50) #TODO: send real parameters + maxI = combineValueAndMultiplier(y["EVSEMaximumCurrentLimit.Value"], y["EVSEMaximumCurrentLimit.Multiplier"]) + maxV = combineValueAndMultiplier(y["EVSEMaximumVoltageLimit.Value"], y["EVSEMaximumVoltageLimit.Multiplier"]) + self.hardwareInterface.setChargerParameters(maxV, maxI) # pull the CP line to state C here: self.hardwareInterface.setStateC() self.addToTrace("Checkpoint555: Locking the connector.") @@ -652,10 +654,13 @@ class fsmPev(): strResponseCode = y["ResponseCode"] strEVSEPresentVoltageValue = y["EVSEPresentVoltage.Value"] strEVSEPresentVoltageMultiplier = y["EVSEPresentVoltage.Multiplier"] + strEVSEPresentCurrentValue = y["EVSEPresentCurrent.Value"] + strEVSEPresentCurrentMultiplier = y["EVSEPresentCurrent.Multiplier"] u = combineValueAndMultiplier(strEVSEPresentVoltageValue, strEVSEPresentVoltageMultiplier) + i = combineValueAndMultiplier(strEVSEPresentCurrentValue, strEVSEPresentCurrentMultiplier) self.callbackShowStatus(format(u,".1f"), "EVSEPresentVoltage") strEVSEStatusCode = y["DC_EVSEStatus.EVSEStatusCode"] - self.hardwareInterface.setChargerVoltageAndCurrent(u, EVTargetCurrent) #TODO: report real current! + self.hardwareInterface.setChargerVoltageAndCurrent(u, i) except: self.addToTrace("ERROR: Could not decode the PreChargeResponse") if (strResponseCode!="OK"): From 3be599e627b872b777f5b773a963edbcd9e7bf8a Mon Sep 17 00:00:00 2001 From: johannes Date: Tue, 20 Jun 2023 22:45:11 +0200 Subject: [PATCH 5/7] Do not use fixed battery voltage when using chademo backend --- hardwareInterface.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hardwareInterface.py b/hardwareInterface.py index acf7348..06ef96c 100644 --- a/hardwareInterface.py +++ b/hardwareInterface.py @@ -182,10 +182,10 @@ class hardwareInterface(): return self.accuMaxCurrent def getAccuMaxVoltage(self): - if getConfigValue("charge_target_voltage"): - self.accuMaxVoltage = getConfigValue("charge_target_voltage") - elif getConfigValue("charge_parameter_backend")=="chademo": + if getConfigValue("charge_parameter_backend")=="chademo": return self.accuMaxVoltage #set by CAN + elif getConfigValue("charge_target_voltage"): + self.accuMaxVoltage = getConfigValue("charge_target_voltage") else: #todo: get max charging voltage from the BMS self.accuMaxVoltage = 230 @@ -240,7 +240,7 @@ class hardwareInterface(): self.contactor_confirmed = False # Confirmation from hardware self.plugged_in = None # None means "not known yet" - self.maxChargerVoltage = 500 + self.maxChargerVoltage = 0 self.maxChargerCurrent = 10 self.chargerVoltage = 0 self.chargerCurrent = 0 @@ -430,7 +430,7 @@ class hardwareInterface(): self.canbus.send(msg) #Report unspecified version 10, this makes our custom implementation send the momentary #battery voltage in 0x100 bytes 0 and 1 - status = 4 #report connector locked + status = 4 if self.maxChargerVoltage > 0 else 0 #report connector locked msg = can.Message(arbitration_id=0x109, data=[ 10, self.chargerVoltage & 0xFF, self.chargerVoltage >> 8, self.chargerCurrent, 0, status, 0, 0], is_extended_id=False) self.canbus.send(msg) From 2b9e1c1d48a55d2e12add34b2ba738e7fc598429 Mon Sep 17 00:00:00 2001 From: johannes Date: Thu, 22 Jun 2023 20:29:44 +0200 Subject: [PATCH 6/7] comments corrected --- hardwareInterface.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hardwareInterface.py b/hardwareInterface.py index 06ef96c..205bcfc 100644 --- a/hardwareInterface.py +++ b/hardwareInterface.py @@ -17,7 +17,7 @@ if (getConfigValue("digital_output_device")=="beaglebone"): import Adafruit_BBIO.GPIO as GPIO if (getConfigValue("charge_parameter_backend")=="chademo"): - # In case we run on beaglebone, we want to use GPIO ports. + # In case we use the CHAdeMO backend, we want to use CAN import can class hardwareInterface(): @@ -425,7 +425,6 @@ class hardwareInterface(): self.addToTrace("CHAdeMO: Set capacity to %d" % message.data[6]) self.capacity = message.data[6] - #TODO: determine maximum charger current and voltage and also actual current and voltage msg = can.Message(arbitration_id=0x108, data=[ 0, self.maxChargerVoltage & 0xFF, self.maxChargerVoltage >> 8, self.maxChargerCurrent, 0, 0, 0, 0], is_extended_id=False) self.canbus.send(msg) #Report unspecified version 10, this makes our custom implementation send the momentary From df274ee085d1ed66c897b91e7f704c633d25209b Mon Sep 17 00:00:00 2001 From: Jorrit Pouw Date: Mon, 26 Jun 2023 19:38:45 +0200 Subject: [PATCH 7/7] extend soc_callback hook with extra info --- doc/pyPlc.ini.template | 2 ++ evseNoGui.py | 34 +++++++++++++++++++++++++++++----- fsmEvse.py | 34 ++++++++++++++++++++-------------- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/doc/pyPlc.ini.template b/doc/pyPlc.ini.template index 3ef1945..9c17037 100644 --- a/doc/pyPlc.ini.template +++ b/doc/pyPlc.ini.template @@ -106,3 +106,5 @@ charge_parameter_backend = chademo # REST callback for SoC states. Comment out to disable. Do not leave a trailing slash soc_callback_enabled = False soc_callback_endpoint = http://1.1.1.1 +# Fallback value to use if the vehicle does not support the EVEnergyCapacity.Value +soc_fallback_energy_capacity = 2700 diff --git a/evseNoGui.py b/evseNoGui.py index dcf1446..24d4f31 100644 --- a/evseNoGui.py +++ b/evseNoGui.py @@ -21,14 +21,38 @@ def cbShowStatus(s, selection=""): soc_callback_enabled = getConfigValueBool("soc_callback_enabled") soc_callback_url = getConfigValue("soc_callback_endpoint") if soc_callback_enabled else "" +soc_fallback_energy_capacity = getConfigValue("soc_fallback_energy_capacity") + +def socStatusCallback(current_soc: int, full_soc: int = -1, energy_capacity: int = -1, energy_request: int = -1, evccid: str = "", origin: str = ""): + # Do some basic value checks and conversions + # Some cars do not support certain values and return 0, make sure we actually send -1 + + if (energy_capacity > 0): + # We need Wh, not something in between kWh and Wh + energy_capacity = energy_capacity * 10 + else: + # Some cars do not supply energy capacity of their battery + # Support some kind of fallback value which would work for installations where typically one car charges + if (int(soc_fallback_energy_capacity) > 0): + energy_capacity = int(soc_fallback_energy_capacity) * 10 + else: + energy_capacity = -1 + + if (energy_request > 0): + # We need Wh, not something in between kWh and Wh + energy_request = energy_request * 10 + else: + energy_request = -1 -def socStatusCallback(remaining_soc: int, full_soc: int = -1, bulk_soc: int = -1, origin: str = ""): print(f"Received SoC status from {origin}.\n" - f" Remaining {remaining_soc}% \n" - f" Full at {full_soc}%\n" - f" Bulk at {bulk_soc}%") + f" Current SoC {current_soc}% \n" + f" Full SoC {full_soc}%\n" + f" Energy capacity {energy_capacity} Wh \n" + f" Energy request {energy_request} Wh \n" + f" EVCCID {evccid} \n") + if soc_callback_enabled: - requests.post(f"{soc_callback_url}/modem?remaining_soc={remaining_soc}&full_soc={full_soc}&bulk_soc={bulk_soc}") + requests.post(f"{soc_callback_url}?current_soc={current_soc}&full_soc={full_soc}&energy_capacity={energy_capacity}&energy_request={energy_request}&evccid={evccid}") myMode = C_EVSE_MODE diff --git a/fsmEvse.py b/fsmEvse.py index d759ca3..38ace4a 100644 --- a/fsmEvse.py +++ b/fsmEvse.py @@ -28,9 +28,9 @@ class fsmEvse(): def publishStatus(self, s): self.callbackShowStatus(s, "evseState") - def publishSoCs(self, remaining_soc: int, full_soc: int = -1, bulk_soc: int = -1, origin: str = ""): + def publishSoCs(self, current_soc: int, full_soc: int = -1, energy_capacity: int = -1, energy_request: int = -1, evccid: str = "", origin: str = ""): if self.callbackSoCStatus is not None: - self.callbackSoCStatus(remaining_soc, full_soc, bulk_soc, origin) + self.callbackSoCStatus(current_soc, full_soc, energy_capacity, energy_request, self.evccid, origin) def enterState(self, n): self.addToTrace("from " + str(self.state) + " entering " + str(n)) @@ -82,6 +82,9 @@ class fsmEvse(): self.Tcp.transmit(msg) self.publishStatus("Session established") self.enterState(stateWaitForServiceDiscoveryRequest) + y = json.loads(strConverterResult) + self.evccid = y.get("EVCCID", "") + if (self.isTooLong()): self.enterState(0) @@ -136,8 +139,8 @@ class fsmEvse(): # todo: check the request content, and fill response parameters self.addToTrace("Received PowerDeliveryReq. Extracting SoC parameters") info = json.loads(strConverterResult) - remaining_soc = int(info.get("EVRESSSOC", -1)) - self.publishSoCs(remaining_soc, origin="PowerDeliveryReq") + current_soc = int(info.get("EVRESSSOC", -1)) + self.publishSoCs(current_soc, origin="PowerDeliveryReq") msg = addV2GTPHeader(exiEncode("EDh")) # EDh for Encode, Din, PowerDeliveryResponse if (testsuite_faultinjection_is_triggered(TC_EVSE_ResponseCode_Failed_for_PowerDeliveryRes)): # send a PowerDeliveryResponse with Responsecode Failed @@ -149,10 +152,11 @@ class fsmEvse(): if (strConverterResult.find("ChargeParameterDiscoveryReq")>0): self.addToTrace("Received ChargeParameterDiscoveryReq. Extracting SoC parameters via DC") info = json.loads(strConverterResult) - remaining_soc = int(info.get("DC_EVStatus.EVRESSSOC", -1)) + current_soc = int(info.get("DC_EVStatus.EVRESSSOC", -1)) full_soc = int(info.get("FullSOC", -1)) - bulk_soc = int(info.get("BulkSOC", -1)) - self.publishSoCs(remaining_soc, full_soc, bulk_soc, origin="ChargeParameterDiscoveryReq") + energy_capacity = int(info.get("EVEnergyCapacity.Value", -1)) + energy_request = int(info.get("EVEnergyRequest.Value", -1)) + self.publishSoCs(current_soc, full_soc, energy_capacity, energy_request, origin="ChargeParameterDiscoveryReq") # todo: check the request content, and fill response parameters msg = addV2GTPHeader(exiEncode("EDe")) # EDe for Encode, Din, ChargeParameterDiscoveryResponse @@ -168,8 +172,8 @@ class fsmEvse(): # todo: make a real cable check, and while it is ongoing, send "Ongoing". self.addToTrace("Received CableCheckReq. Extracting SoC parameters via DC") info = json.loads(strConverterResult) - remaining_soc = int(info.get("DC_EVStatus.EVRESSSOC", -1)) - self.publishSoCs(remaining_soc, -1, -1, origin="CableCheckReq") + current_soc = int(info.get("DC_EVStatus.EVRESSSOC", -1)) + self.publishSoCs(current_soc, -1, -1, origin="CableCheckReq") msg = addV2GTPHeader(exiEncode("EDf")) # EDf for Encode, Din, CableCheckResponse if (testsuite_faultinjection_is_triggered(TC_EVSE_ResponseCode_Failed_for_CableCheckRes)): @@ -232,13 +236,14 @@ class fsmEvse(): strEVTargetVoltageMultiplier = y["EVTargetVoltage.Multiplier"] uTarget = combineValueAndMultiplier(strEVTargetVoltageValue, strEVTargetVoltageMultiplier) self.addToTrace("EV wants EVTargetVoltage " + str(uTarget)) - - remaining_soc = int(y.get("DC_EVStatus.EVRESSSOC", -1)) + current_soc = int(y.get("DC_EVStatus.EVRESSSOC", -1)) full_soc = int(y.get("FullSOC", -1)) - bulk_soc = int(y.get("BulkSOC", -1)) - self.publishSoCs(remaining_soc, full_soc, bulk_soc, origin="CurrentDemandReq") + energy_capacity = int(y.get("EVEnergyCapacity.Value", -1)) + energy_request = int(y.get("EVEnergyRequest.Value", -1)) - self.callbackShowStatus(str(remaining_soc), "soc") + self.publishSoCs(current_soc, full_soc, energy_capacity, energy_request, origin="CurrentDemandReq") + + self.callbackShowStatus(str(current_soc), "soc") except: self.addToTrace("ERROR: Could not decode the CurrentDemandReq") @@ -352,6 +357,7 @@ class fsmEvse(): self.state = 0 self.cyclesInState = 0 self.rxData = [] + self.evccid = "" def mainfunction(self): self.Tcp.mainfunction() # call the lower-level worker