-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbase_classes.py
165 lines (139 loc) · 5.51 KB
/
base_classes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
from abc import ABC
from enum import Enum
from typing import Optional
class ChargingState(Enum):
"""
Charging state as described in DIN EN 61851-1:2012
For a short summary see: https://evsim.gonium.net/#der-control-pilot-cp
"""
A = "A"
B = "B"
C = "C"
D = "D"
E = "E"
F = "F"
class ProximityPilotResitorValue(Enum):
"""
Resistance values between PP and PE as defined in DIN EN 61851-1:2012
For a short summary see: https://evsim.gonium.net/#der-proximity-plug-pp
"""
Charge63A = 100
Charge32A = 220
Charge20A = 680
Charge13A = 1500
class ChargingStation(ABC):
def get_state(self) -> ChargingState:
"""
Get the current charging state according to the voltage measured between CP and PE
"""
raise NotImplementedError()
def set_cable_lock(self, locked: bool):
"""
Lock or release the charging cable
"""
raise NotImplementedError()
def set_pwm_duty_cycle(self, dutycycle: float):
"""
Set the dutycycle of the PWM between CP and PE.
The parameter dutycycle is in %. Thus a value of 20 refers to 10A charging current.
A value of 5 signals the vehicle to use higher level communication.
"""
raise NotImplementedError()
def get_max_charge_current(self) -> ProximityPilotResitorValue:
"""
Get the current resistance between PP and PE in Ohms, which defines the maximum current of the cable.
This value is usually ignored in ISO15118 use cases, but important for AC charging stations.
If the resistance is not one of the values defined in DIN EN 61851-1:2012 this function shall raise a ValueError
"""
raise NotImplementedError()
def set_max_charge_current(self, current: int):
"""
Signal the vehicle the maximum allowed current to be drawn (through the PWM signal between CP and PE).
This is usually only used for AC charging.
This function raises a ValueError for too high or too low current values.
"""
if current < 6:
raise ValueError("Charge current cannot be lower than 6A")
elif current <= 51:
self.set_pwm_duty_cycle(current / 0.6)
elif current <= 80:
self.set_pwm_duty_cycle(current / 2.5 + 64)
else:
raise ValueError("Charge current cannot be higher than 80A")
class ElectricVehicle(ABC):
def get_state(self) -> ChargingState:
"""
Get the current charging state according to the voltage measured between CP and PE
"""
raise NotImplementedError()
def set_state(self, state: ChargingState):
"""
Set the diode/resistor communication (charging state)
Can raise a NotImplementedError if switching to the given ChargingState is not supported/implemented
"""
raise NotImplementedError()
def set_cable_lock(self, locked: bool):
"""
Lock or release the charging cable
"""
raise NotImplementedError()
def get_pwm_duty_cycle(self) -> float:
"""
Get the current duty cycle of the PWM signal CP and PE in %
"""
raise NotImplementedError()
def get_max_charge_current(self) -> int:
"""
Calculate the maximum charge current communicated by the charging
station through the dutycycle of the PWM between CP and PE.
The returned value is in Ampere.
"""
dutycycle = self.get_pwm_duty_cycle()
# we give a PWM tolerance based on the rounding error from float to int
if dutycycle < 5.5 / 0.6 or dutycycle >= 80.5 / 2.5 + 64:
raise ValueError(f"Unexpected dutycycle value of {dutycycle}%")
if dutycycle < 85:
return round(dutycycle * 0.6)
else:
return round((dutycycle - 64) * 2.5)
def set_max_charge_current(self, resistance: Optional[ProximityPilotResitorValue]):
"""
Set the maximum charge current communicated to the vehicle through the
resistor between PP and PE.
Giving None as a parameter shall turn off the resistor.
This is only used for AC charging and most of the times already included
in the charging cable.
"""
raise NotImplementedError()
class HighVoltageSource(ABC):
def check_insulation(self) -> bool:
"""
Perform insulation and cable checks.
Return True when successful, False otherwise.
"""
raise NotImplementedError()
def get_voltage(self) -> float:
"""
Get the current voltage measured
"""
raise NotImplementedError()
def get_current(self) -> float:
"""
Get the current amperage going into (or out of) the battery
Positive means charging, negative means discharging.
"""
raise NotImplementedError()
def set_charging_target(
self, current: float, min_voltage: float, max_voltage: float
):
"""
Set the target parameters for charging.
The goal is to charging/discharging the battery with `current` amps,
appying a minimum and maximum voltage of `min_voltage` and
`max_voltage` Volts respectively.
Positive `current` means charging, negative means discharging.
When 0 is given for all parameter output shall be turned off.
If the device supports only one of charging and discharging, but the
other one is requested, this function shall throw a ValueError.
"""
raise NotImplementedError()