mirror of
https://github.com/uhi22/pyPLC.git
synced 2024-11-20 01:13:58 +00:00
fix: pevmode: wait for contactors closed (in work). feature: more config options
This commit is contained in:
parent
893ade2e9f
commit
14b1cdb2ff
5 changed files with 141 additions and 15 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,7 @@
|
|||
.*
|
||||
/__pycache__/
|
||||
/doc/*.jar
|
||||
*.bat
|
||||
PevExiLog*.txt
|
||||
pyPlc.ini
|
||||
/log
|
||||
|
|
77
doc/pyPlc.ini.template
Normal file
77
doc/pyPlc.ini.template
Normal file
|
@ -0,0 +1,77 @@
|
|||
# This is the template file pyPlc.ini.template.
|
||||
# Copy this file in the same folder like the pyPlc.py, and rename it to pyPlc.ini
|
||||
|
||||
[general]
|
||||
# mode can be either PevMode to use as car, or EvseMode to use as charger
|
||||
mode = PevMode
|
||||
|
||||
# Simulation without modem
|
||||
# For development purposes, make it possible to run two instances (pev and evse) on one machine, without
|
||||
# a modem connected. This feature is not tested since a long time, most likely does not work as intended.
|
||||
# todo: replace isSimulationMode by this setting
|
||||
is_simulation_without_modems = false
|
||||
|
||||
# The Ethernet interface. Usually eth0 on Raspberry.
|
||||
# Todo: This setting is considered only on linux. Find a clean solution for windows is to be done.
|
||||
eth_interface = eth0
|
||||
|
||||
# If a display is connected via serial line, e.g. an WIFI-KIT-32 running the software from https://github.com/uhi22/SerialToOLED
|
||||
display_via_serial = yes
|
||||
|
||||
# LightBulbDemo turns on the relay with a short delay in the charging loop, to stabilize the voltage
|
||||
# before the resistive load is connected.
|
||||
light_bulb_demo = no
|
||||
|
||||
# SOC simulation.
|
||||
# In PevMode, simulate a rising SOC while charging.
|
||||
soc_simulation = yes
|
||||
|
||||
# Device selection for the digital outputs, for CP state and power relays
|
||||
# Possible options:
|
||||
# dieter: Serial controlled device, which controls the digital outputs. E.g. arduino from https://github.com/uhi22/dieter
|
||||
# beaglebone: GPIO pins of the beagleBone, as used in https://github.com/jsphuebner/pyPLC/tree/beaglebone
|
||||
# celeron55device: Serial controlled device as used in https://openinverter.org/forum/viewtopic.php?p=56192#p56192
|
||||
digital_output_device = dieter
|
||||
#digital_output_device = beaglebone
|
||||
#digital_output_device = celeron55device
|
||||
|
||||
|
||||
# Device to read the physically measured inlet voltage in PevMode
|
||||
# Possible options:
|
||||
# dieter: The high-voltage dieter from https://github.com/uhi22/dieter, which is connected on serial port.
|
||||
# none: if no measurement is intended.
|
||||
# celeron55device: as used in https://openinverter.org/forum/viewtopic.php?p=56192#p56192
|
||||
#analog_input_device = dieter
|
||||
analog_input_device = none
|
||||
#analog_input_device = celeron55device
|
||||
|
||||
|
||||
# Criteria for ending the PreCharge phase in PevMode
|
||||
# Possible options:
|
||||
# yes: use the EVSEPresentVoltage which is reported by the charger, to decide the end of the precharge
|
||||
# no: use the physically measured inlet voltage to decide the end of the precharge
|
||||
use_evsepresentvoltage_for_precharge_end = yes
|
||||
|
||||
# Use the physically measured inlet voltage to show on display during the charge loop.
|
||||
# If false, we are showing the EVSEPresentVoltage which is reported by the charger.
|
||||
use_physical_inlet_voltage_during_chargeloop = no
|
||||
|
||||
# Voltage threshold for the end-of-precharge decision
|
||||
# This is the maximum difference voltage between the charger voltage and the accu voltage. If the actual voltage
|
||||
# difference is lower than this threshold, we will close the power relay, to connect the accu to the charger.
|
||||
# Unit: volt
|
||||
u_delta_max_for_end_of_precharge = 10
|
||||
|
||||
# Added by celeron55
|
||||
# The serial port and baud rate used for communication. Used
|
||||
# for serial devices like Dieter, OLED-Display and
|
||||
# celeron55's measuring and switching device
|
||||
serial_port = /dev/ttyS1
|
||||
serial_baud = 115200
|
||||
|
||||
# The target voltage used in the CurrentDemandRequest.
|
||||
# This is a value for first try-outs. Better would
|
||||
# be if the BMS would provide the value.
|
||||
# 11 * 6 * 4.1V = 66 * 4.1V = 270V
|
||||
charge_target_voltage = 270
|
||||
|
47
fsmPev.py
47
fsmPev.py
|
@ -24,11 +24,12 @@ stateWaitForContractAuthenticationResponse = 7
|
|||
stateWaitForChargeParameterDiscoveryResponse = 8
|
||||
stateWaitForCableCheckResponse = 9
|
||||
stateWaitForPreChargeResponse = 10
|
||||
stateWaitForPowerDeliveryResponse = 11
|
||||
stateWaitForCurrentDemandResponse = 12
|
||||
stateWaitForWeldingDetectionResponse = 13
|
||||
stateWaitForSessionStopResponse = 14
|
||||
stateChargingFinished = 15
|
||||
stateWaitForContactorsClosed = 11
|
||||
stateWaitForPowerDeliveryResponse = 12
|
||||
stateWaitForCurrentDemandResponse = 13
|
||||
stateWaitForWeldingDetectionResponse = 14
|
||||
stateWaitForSessionStopResponse = 15
|
||||
stateChargingFinished = 16
|
||||
stateSequenceTimeout = 99
|
||||
|
||||
|
||||
|
@ -81,6 +82,8 @@ class fsmPev():
|
|||
s = "WaitForCableCheckResponse"
|
||||
if (statenumber == stateWaitForPreChargeResponse):
|
||||
s = "WaitForPreChargeResponse"
|
||||
if (statenumber == stateWaitForContactorsClosed):
|
||||
s = "WaitForContactorsClosed"
|
||||
if (statenumber == stateWaitForPowerDeliveryResponse):
|
||||
s = "WaitForPowerDeliveryResponse"
|
||||
if (statenumber == stateWaitForCurrentDemandResponse):
|
||||
|
@ -408,20 +411,17 @@ class fsmPev():
|
|||
s= s + "U_Accu " + str(self.hardwareInterface.getAccuVoltage()) + "V"
|
||||
self.addToTrace(s)
|
||||
if (abs(u-self.hardwareInterface.getAccuVoltage()) < float(getConfigValue("u_delta_max_for_end_of_precharge"))):
|
||||
self.addToTrace("Difference between accu voltage and inlet voltage is small. Sending PowerDeliveryReq.")
|
||||
self.addToTrace("Difference between accu voltage and inlet voltage is small.")
|
||||
self.publishStatus("PreCharge done")
|
||||
if (self.isLightBulbDemo):
|
||||
# For light-bulb-demo, nothing to do here.
|
||||
self.addToTrace("This is a light bulb demo. Do not turn-on the relay at end of precharge.")
|
||||
else:
|
||||
# In real-world-case, turn the power relay on.
|
||||
self.addToTrace("Checkpoint590: Turning the contactors on.")
|
||||
self.hardwareInterface.setPowerRelayOn()
|
||||
soc = self.hardwareInterface.getSoc()
|
||||
msg = addV2GTPHeader(self.exiEncode("EDH_"+self.sessionId+"_"+ str(soc) + "_" + "1")) # EDH for Encode, Din, PowerDeliveryReq, ON
|
||||
self.wasPowerDeliveryRequestedOn=True
|
||||
self.addToTrace("responding " + prettyHexMessage(msg))
|
||||
self.Tcp.transmit(msg)
|
||||
self.enterState(stateWaitForPowerDeliveryResponse)
|
||||
self.DelayCycles = 10 # 10*33ms = 330ms waiting for contactors
|
||||
self.enterState(stateWaitForContactorsClosed)
|
||||
else:
|
||||
self.publishStatus("PreChrge ongoing", format(u, ".0f") + "V")
|
||||
self.addToTrace("Difference too big. Continuing PreCharge.")
|
||||
|
@ -434,6 +434,28 @@ class fsmPev():
|
|||
if (self.isTooLong()):
|
||||
self.enterState(stateSequenceTimeout)
|
||||
|
||||
def stateFunctionWaitForContactorsClosed(self):
|
||||
if (self.DelayCycles>0):
|
||||
self.DelayCycles-=1
|
||||
return
|
||||
if (self.isLightBulbDemo):
|
||||
readyForNextState=1 # if it's just a bulb demo, we do not wait for contactor, because it is not switched in this moment.
|
||||
else:
|
||||
readyForNextState = self.hardwareInterface.getPowerRelayConfirmation() # check if the contactor is closed
|
||||
if (readyForNextState):
|
||||
self.addToTrace("Contactors are confirmed to be closed.")
|
||||
self.publishStatus("Contactors ON")
|
||||
if (readyForNextState):
|
||||
self.addToTrace("Sending PowerDeliveryReq.")
|
||||
soc = self.hardwareInterface.getSoc()
|
||||
msg = addV2GTPHeader(self.exiEncode("EDH_"+self.sessionId+"_"+ str(soc) + "_" + "1")) # EDH for Encode, Din, PowerDeliveryReq, ON
|
||||
self.wasPowerDeliveryRequestedOn=True
|
||||
self.addToTrace("responding " + prettyHexMessage(msg))
|
||||
self.Tcp.transmit(msg)
|
||||
self.enterState(stateWaitForPowerDeliveryResponse)
|
||||
if (self.isTooLong()):
|
||||
self.enterState(stateSequenceTimeout)
|
||||
|
||||
def stateFunctionWaitForPowerDeliveryResponse(self):
|
||||
if (len(self.rxData)>0):
|
||||
self.addToTrace("In state WaitForPowerDeliveryRes, received " + prettyHexMessage(self.rxData))
|
||||
|
@ -568,6 +590,7 @@ class fsmPev():
|
|||
stateWaitForChargeParameterDiscoveryResponse: stateFunctionWaitForChargeParameterDiscoveryResponse,
|
||||
stateWaitForCableCheckResponse: stateFunctionWaitForCableCheckResponse,
|
||||
stateWaitForPreChargeResponse: stateFunctionWaitForPreChargeResponse,
|
||||
stateWaitForContactorsClosed: stateFunctionWaitForContactorsClosed,
|
||||
stateWaitForPowerDeliveryResponse: stateFunctionWaitForPowerDeliveryResponse,
|
||||
stateWaitForCurrentDemandResponse: stateFunctionWaitForCurrentDemandResponse,
|
||||
stateWaitForWeldingDetectionResponse: stateFunctionWaitForWeldingDetectionResponse,
|
||||
|
|
|
@ -89,6 +89,9 @@ class hardwareInterface():
|
|||
self.addToTrace("Switching Relay2 OFF.")
|
||||
self.outvalue &= ~4
|
||||
|
||||
def getPowerRelayConfirmation(self):
|
||||
return 1 # todo: self.contactor_confirmed
|
||||
|
||||
def getInletVoltage(self):
|
||||
# uncomment this line, to take the simulated inlet voltage instead of the really measured
|
||||
# self.inletVoltage = self.simulatedInletVoltage
|
||||
|
|
26
pyPlc.ini
26
pyPlc.ini
|
@ -18,7 +18,7 @@ display_via_serial = yes
|
|||
|
||||
# LightBulbDemo turns on the relay with a short delay in the charging loop, to stabilize the voltage
|
||||
# before the resistive load is connected.
|
||||
light_bulb_demo = yes
|
||||
light_bulb_demo = no
|
||||
|
||||
# SOC simulation.
|
||||
# In PevMode, simulate a rising SOC while charging.
|
||||
|
@ -28,14 +28,21 @@ soc_simulation = yes
|
|||
# Possible options:
|
||||
# dieter: Serial controlled device, which controls the digital outputs. E.g. arduino from https://github.com/uhi22/dieter
|
||||
# beaglebone: GPIO pins of the beagleBone, as used in https://github.com/jsphuebner/pyPLC/tree/beaglebone
|
||||
# celeron55device: Serial controlled device as used in https://openinverter.org/forum/viewtopic.php?p=56192#p56192
|
||||
digital_output_device = dieter
|
||||
#digital_output_device = beaglebone
|
||||
#digital_output_device = celeron55device
|
||||
|
||||
|
||||
# Device to read the physically measured inlet voltage in PevMode
|
||||
# Either the high-voltage dieter from https://github.com/uhi22/dieter, which is connected on serial port.
|
||||
# Or "none", if no measurement is intended.
|
||||
# Possible options:
|
||||
# dieter: The high-voltage dieter from https://github.com/uhi22/dieter, which is connected on serial port.
|
||||
# none: if no measurement is intended.
|
||||
# celeron55device: as used in https://openinverter.org/forum/viewtopic.php?p=56192#p56192
|
||||
#analog_input_device = dieter
|
||||
analog_input_device = none
|
||||
#analog_input_device = celeron55device
|
||||
|
||||
|
||||
# Criteria for ending the PreCharge phase in PevMode
|
||||
# Possible options:
|
||||
|
@ -53,3 +60,16 @@ use_physical_inlet_voltage_during_chargeloop = no
|
|||
# Unit: volt
|
||||
u_delta_max_for_end_of_precharge = 10
|
||||
|
||||
# Added by celeron55
|
||||
# The serial port and baud rate used for communication. Used
|
||||
# for serial devices like Dieter, OLED-Display and
|
||||
# celeron55's measuring and switching device
|
||||
serial_port = /dev/ttyS1
|
||||
serial_baud = 115200
|
||||
|
||||
# The target voltage used in the CurrentDemandRequest.
|
||||
# This is a value for first try-outs. Better would
|
||||
# be if the BMS would provide the value.
|
||||
# 11 * 6 * 4.1V = 66 * 4.1V = 270V
|
||||
charge_target_voltage = 270
|
||||
|
||||
|
|
Loading…
Reference in a new issue