@@ -37,6 +37,7 @@ class ChargeMode(str, enum.Enum):
3737
3838@enum .unique
3939class PhaseMode (str , enum .Enum ):
40+ DISABLED = "DISABLED" # phase relay is not in operation
4041 AUTO = "AUTO" # PV switches between 1 and 3 phases
4142 CHARGE_1P = "CHARGE_1P"
4243 CHARGE_3P = "CHARGE_3P"
@@ -53,6 +54,7 @@ class ChargeControllerData(BaseData):
5354class ChargeControllerConfig (BaseConfig ):
5455 cycle_time : int = 30 # [s] control loop cycle time, used by scheduler
5556 enable_phase_switching : bool = True # set to False of phase relay is not in operation
57+ enable_phase_switching_on_host_only = "" # if set, phase switching is only allowed when running on specified host (env var: HOSTNAME)
5658 enable_auto_phase_switching : bool = True # automatic phase switching depending on available PV
5759 enable_charging_when_connecting_car : ChargeMode = ChargeMode .OFF
5860 line_voltage : float = 230 # [V]
@@ -80,7 +82,8 @@ class ChargeController(BaseService[ChargeControllerConfig, ChargeControllerData]
8082 "pvcontrol_controller_charged_energy_wh_total" , "Energy charged into car by source" , ["source" ]
8183 )
8284
83- def __init__ (self , config : ChargeControllerConfig , meter : Meter , wallbox : Wallbox ):
85+ # hostname - optional parameter to enable/disable phase switching depending on where pvcontrol runs (k8s hostname)
86+ def __init__ (self , config : ChargeControllerConfig , meter : Meter , wallbox : Wallbox , hostname = "" ):
8487 super ().__init__ (config )
8588 self ._meter = meter
8689 self ._wallbox = wallbox
@@ -93,6 +96,9 @@ def __init__(self, config: ChargeControllerConfig, meter: Meter, wallbox: Wallbo
9396 self ._last_energy_consumption = 0.0 # total counter value, must be initialized first with data from meter
9497 self ._last_energy_consumption_grid = 0.0 # total counter value, must be initialized first with data from meter
9598 # config
99+ self ._enable_phase_switching = self ._is_enable_phase_switching (hostname )
100+ if not self ._enable_phase_switching :
101+ self .set_phase_mode (PhaseMode .DISABLED )
96102 self ._min_supported_current = wallbox .get_config ().min_supported_current
97103 self ._max_supported_current = wallbox .get_config ().max_supported_current
98104 min_power_1phase = self ._min_supported_current * config .line_voltage
@@ -110,11 +116,19 @@ def __init__(self, config: ChargeControllerConfig, meter: Meter, wallbox: Wallbo
110116 ChargeController ._metrics_pvc_controller_charged_energy .labels ("grid" )
111117 ChargeController ._metrics_pvc_controller_charged_energy .labels ("pv" )
112118
119+ def _is_enable_phase_switching (self , hostname : str ) -> bool :
120+ if self .get_config ().enable_phase_switching :
121+ require_hostname = self .get_config ().enable_phase_switching_on_host_only
122+ return not require_hostname or require_hostname == hostname
123+ return False
124+
113125 def set_desired_mode (self , mode : ChargeMode ) -> None :
114126 logger .info (f"set_desired_mode: { self .get_data ().desired_mode } -> { mode } " )
115127 self .get_data ().desired_mode = mode
116128
117129 def set_phase_mode (self , mode : PhaseMode ) -> None :
130+ if not self ._enable_phase_switching :
131+ mode = PhaseMode .DISABLED
118132 self .get_data ().phase_mode = mode
119133
120134 @_metrics_pvc_controller_processing .time ()
@@ -212,8 +226,7 @@ def _converge_phases(self, m: MeterData, wb: WallboxData) -> bool:
212226 self ._wallbox .trigger_reset ()
213227 return True
214228
215- config = self .get_config ()
216- if config .enable_phase_switching :
229+ if self ._enable_phase_switching :
217230 available_power = - m .power_grid + wb .power
218231 desired_phases = self ._desired_phases (available_power , wb .phases_in )
219232 if wb .error == 0 and desired_phases != wb .phases_in :
@@ -224,11 +237,7 @@ def _converge_phases(self, m: MeterData, wb: WallboxData) -> bool:
224237 # charging off and wait one cylce
225238 self ._set_allow_charging (False , skip_delay = True )
226239 return True
227- else :
228- return False
229- else :
230- self .set_phase_mode (PhaseMode .CHARGE_1P if wb .phases_in == 1 else PhaseMode .CHARGE_3P )
231- return False
240+ return False
232241
233242 def _desired_phases (self , available_power : float , current_phases : int ):
234243 # TODO 2 phase charging
@@ -341,5 +350,5 @@ def _set_allow_charging(self, v: bool, skip_delay: bool = False):
341350
342351class ChargeControllerFactory :
343352 @classmethod
344- def newController (cls , meter : Meter , wb : Wallbox , ** kwargs ) -> ChargeController :
345- return ChargeController (ChargeControllerConfig (** kwargs ), meter , wb )
353+ def newController (cls , meter : Meter , wb : Wallbox , hostname = "" , ** kwargs ) -> ChargeController :
354+ return ChargeController (ChargeControllerConfig (** kwargs ), meter , wb , hostname )
0 commit comments