Skip to content

Commit e27e4ec

Browse files
authored
Improvements to EVChargerData coming from the microgrid API (#848)
- A new method `is_ev_connected` to analyze the states better - New fields to represent active power bounds for ev chargers
2 parents 1595a5f + 7e52a79 commit e27e4ec

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

src/frequenz/sdk/microgrid/component/_component_data.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,50 @@ class EVChargerData(ComponentData):
356356
wire for phase/line 1,2 and 3 respectively.
357357
"""
358358

359+
active_power_inclusion_lower_bound: float
360+
"""Lower inclusion bound for EV charger power in watts.
361+
362+
This is the lower limit of the range within which power requests are allowed for the
363+
EV charger.
364+
365+
See [`frequenz.api.common.metrics_pb2.Metric.system_inclusion_bounds`][] and
366+
[`frequenz.api.common.metrics_pb2.Metric.system_exclusion_bounds`][] for more
367+
details.
368+
"""
369+
370+
active_power_exclusion_lower_bound: float
371+
"""Lower exclusion bound for EV charger power in watts.
372+
373+
This is the lower limit of the range within which power requests are not allowed for
374+
the EV charger.
375+
376+
See [`frequenz.api.common.metrics_pb2.Metric.system_inclusion_bounds`][] and
377+
[`frequenz.api.common.metrics_pb2.Metric.system_exclusion_bounds`][] for more
378+
details.
379+
"""
380+
381+
active_power_inclusion_upper_bound: float
382+
"""Upper inclusion bound for EV charger power in watts.
383+
384+
This is the upper limit of the range within which power requests are allowed for the
385+
EV charger.
386+
387+
See [`frequenz.api.common.metrics_pb2.Metric.system_inclusion_bounds`][] and
388+
[`frequenz.api.common.metrics_pb2.Metric.system_exclusion_bounds`][] for more
389+
details.
390+
"""
391+
392+
active_power_exclusion_upper_bound: float
393+
"""Upper exclusion bound for EV charger power in watts.
394+
395+
This is the upper limit of the range within which power requests are not allowed for
396+
the EV charger.
397+
398+
See [`frequenz.api.common.metrics_pb2.Metric.system_inclusion_bounds`][] and
399+
[`frequenz.api.common.metrics_pb2.Metric.system_exclusion_bounds`][] for more
400+
details.
401+
"""
402+
359403
frequency: float
360404
"""AC frequency, in Hertz (Hz)."""
361405

@@ -375,10 +419,11 @@ def from_proto(cls, raw: microgrid_pb.ComponentData) -> EVChargerData:
375419
Returns:
376420
Instance of EVChargerData created from the protobuf message.
377421
"""
422+
raw_power = raw.ev_charger.data.ac.power_active
378423
ev_charger_data = cls(
379424
component_id=raw.id,
380425
timestamp=raw.ts.ToDatetime(tzinfo=timezone.utc),
381-
active_power=raw.ev_charger.data.ac.power_active.value,
426+
active_power=raw_power.value,
382427
current_per_phase=(
383428
raw.ev_charger.data.ac.phase_1.current.value,
384429
raw.ev_charger.data.ac.phase_2.current.value,
@@ -389,6 +434,10 @@ def from_proto(cls, raw: microgrid_pb.ComponentData) -> EVChargerData:
389434
raw.ev_charger.data.ac.phase_2.voltage.value,
390435
raw.ev_charger.data.ac.phase_3.voltage.value,
391436
),
437+
active_power_inclusion_lower_bound=raw_power.system_inclusion_bounds.lower,
438+
active_power_exclusion_lower_bound=raw_power.system_exclusion_bounds.lower,
439+
active_power_inclusion_upper_bound=raw_power.system_inclusion_bounds.upper,
440+
active_power_exclusion_upper_bound=raw_power.system_exclusion_bounds.upper,
392441
cable_state=EVChargerCableState.from_pb(raw.ev_charger.state.cable_state),
393442
component_state=EVChargerComponentState.from_pb(
394443
raw.ev_charger.state.component_state
@@ -397,3 +446,18 @@ def from_proto(cls, raw: microgrid_pb.ComponentData) -> EVChargerData:
397446
)
398447
ev_charger_data._set_raw(raw=raw)
399448
return ev_charger_data
449+
450+
def is_ev_connected(self) -> bool:
451+
"""Check whether an EV is connected to the charger.
452+
453+
Returns:
454+
When the charger is not in an error state, whether an EV is connected to
455+
the charger.
456+
"""
457+
return self.component_state not in (
458+
EVChargerComponentState.AUTHORIZATION_REJECTED,
459+
EVChargerComponentState.ERROR,
460+
) and self.cable_state in (
461+
EVChargerCableState.EV_LOCKED,
462+
EVChargerCableState.EV_PLUGGED,
463+
)

tests/utils/component_data_wrapper.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ def __init__( # pylint: disable=too-many-arguments
159159
active_power: float = math.nan,
160160
current_per_phase: tuple[float, float, float] = (math.nan, math.nan, math.nan),
161161
voltage_per_phase: tuple[float, float, float] = (math.nan, math.nan, math.nan),
162+
active_power_inclusion_lower_bound: float = math.nan,
163+
active_power_exclusion_lower_bound: float = math.nan,
164+
active_power_inclusion_upper_bound: float = math.nan,
165+
active_power_exclusion_upper_bound: float = math.nan,
162166
frequency: float = 50.0,
163167
cable_state: EVChargerCableState = EVChargerCableState.UNSPECIFIED,
164168
component_state: EVChargerComponentState = EVChargerComponentState.UNSPECIFIED,
@@ -174,6 +178,10 @@ def __init__( # pylint: disable=too-many-arguments
174178
active_power=active_power,
175179
current_per_phase=current_per_phase,
176180
voltage_per_phase=voltage_per_phase,
181+
active_power_inclusion_lower_bound=active_power_inclusion_lower_bound,
182+
active_power_exclusion_lower_bound=active_power_exclusion_lower_bound,
183+
active_power_inclusion_upper_bound=active_power_inclusion_upper_bound,
184+
active_power_exclusion_upper_bound=active_power_exclusion_upper_bound,
177185
frequency=frequency,
178186
cable_state=cable_state,
179187
component_state=component_state,

0 commit comments

Comments
 (0)