Skip to content

Commit 6d4f2ad

Browse files
committed
Rewrite component data wrapper classes to not redefine data fields
These classes were redefining all parameters, and that had the risk of going out of sync with the fields in the base class. This PR ties the wrappers with their base classes, such that it is easy to identify changes to the base classes, without updates to the wrappers. Signed-off-by: Sahas Subramanian <[email protected]>
1 parent 8c9bcae commit 6d4f2ad

File tree

1 file changed

+127
-40
lines changed

1 file changed

+127
-40
lines changed

tests/utils/component_data_wrapper.py

Lines changed: 127 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from __future__ import annotations
1414

1515
import math
16-
from dataclasses import dataclass, field, replace
16+
from dataclasses import dataclass, replace
1717
from datetime import datetime
1818
from typing import Tuple
1919

@@ -30,24 +30,47 @@
3030
)
3131

3232

33-
@dataclass(frozen=True)
3433
class BatteryDataWrapper(BatteryData):
3534
"""Wrapper for the BatteryData with default arguments."""
3635

37-
soc: float = math.nan
38-
soc_lower_bound: float = math.nan
39-
soc_upper_bound: float = math.nan
40-
capacity: float = math.nan
41-
power_lower_bound: float = math.nan
42-
power_upper_bound: float = math.nan
43-
temperature_max: float = math.nan
44-
_relay_state: battery_pb.RelayState.ValueType = (
45-
battery_pb.RelayState.RELAY_STATE_UNSPECIFIED
46-
)
47-
_component_state: battery_pb.ComponentState.ValueType = (
48-
battery_pb.ComponentState.COMPONENT_STATE_UNSPECIFIED
49-
)
50-
_errors: list[battery_pb.Error] = field(default_factory=list)
36+
def __init__( # pylint: disable=too-many-arguments
37+
self,
38+
component_id: int,
39+
timestamp: datetime,
40+
soc: float = math.nan,
41+
soc_lower_bound: float = math.nan,
42+
soc_upper_bound: float = math.nan,
43+
capacity: float = math.nan,
44+
power_lower_bound: float = math.nan,
45+
power_upper_bound: float = math.nan,
46+
temperature_max: float = math.nan,
47+
_relay_state: battery_pb.RelayState.ValueType = (
48+
battery_pb.RelayState.RELAY_STATE_UNSPECIFIED
49+
),
50+
_component_state: battery_pb.ComponentState.ValueType = (
51+
battery_pb.ComponentState.COMPONENT_STATE_UNSPECIFIED
52+
),
53+
_errors: list[battery_pb.Error] | None = None,
54+
) -> None:
55+
"""Initialize the BatteryDataWrapper.
56+
57+
This is a wrapper for the BatteryData with default arguments. The parameters are
58+
documented in the BatteryData class.
59+
"""
60+
super().__init__(
61+
component_id=component_id,
62+
timestamp=timestamp,
63+
soc=soc,
64+
soc_lower_bound=soc_lower_bound,
65+
soc_upper_bound=soc_upper_bound,
66+
capacity=capacity,
67+
power_lower_bound=power_lower_bound,
68+
power_upper_bound=power_upper_bound,
69+
temperature_max=temperature_max,
70+
_relay_state=_relay_state,
71+
_component_state=_component_state,
72+
_errors=_errors if _errors else [],
73+
)
5174

5275
def copy_with_new_timestamp(self, new_timestamp: datetime) -> BatteryDataWrapper:
5376
"""Copy the component data but insert new timestamp.
@@ -68,13 +91,32 @@ def copy_with_new_timestamp(self, new_timestamp: datetime) -> BatteryDataWrapper
6891
class InverterDataWrapper(InverterData):
6992
"""Wrapper for the InverterData with default arguments."""
7093

71-
active_power: float = math.nan
72-
active_power_lower_bound: float = math.nan
73-
active_power_upper_bound: float = math.nan
74-
_component_state: inverter_pb.ComponentState.ValueType = (
75-
inverter_pb.ComponentState.COMPONENT_STATE_UNSPECIFIED
76-
)
77-
_errors: list[inverter_pb.Error] = field(default_factory=list)
94+
def __init__( # pylint: disable=too-many-arguments
95+
self,
96+
component_id: int,
97+
timestamp: datetime,
98+
active_power: float = math.nan,
99+
active_power_lower_bound: float = math.nan,
100+
active_power_upper_bound: float = math.nan,
101+
_component_state: inverter_pb.ComponentState.ValueType = (
102+
inverter_pb.ComponentState.COMPONENT_STATE_UNSPECIFIED
103+
),
104+
_errors: list[inverter_pb.Error] | None = None,
105+
) -> None:
106+
"""Initialize the InverterDataWrapper.
107+
108+
This is a wrapper for the InverterData with default arguments. The parameters
109+
are documented in the InverterData class.
110+
"""
111+
super().__init__(
112+
component_id=component_id,
113+
timestamp=timestamp,
114+
active_power=active_power,
115+
active_power_lower_bound=active_power_lower_bound,
116+
active_power_upper_bound=active_power_upper_bound,
117+
_component_state=_component_state,
118+
_errors=_errors if _errors else [],
119+
)
78120

79121
def copy_with_new_timestamp(self, new_timestamp: datetime) -> InverterDataWrapper:
80122
"""Copy the component data but insert new timestamp.
@@ -95,15 +137,38 @@ def copy_with_new_timestamp(self, new_timestamp: datetime) -> InverterDataWrappe
95137
class EvChargerDataWrapper(EVChargerData):
96138
"""Wrapper for the EvChargerData with default arguments."""
97139

98-
active_power: float = math.nan
99-
current_per_phase: Tuple[float, float, float] = field(
100-
default_factory=lambda: (math.nan, math.nan, math.nan)
101-
)
102-
voltage_per_phase: Tuple[float, float, float] = field(
103-
default_factory=lambda: (math.nan, math.nan, math.nan)
104-
)
105-
cable_state: EVChargerCableState = EVChargerCableState.UNSPECIFIED
106-
component_state: EVChargerComponentState = EVChargerComponentState.UNSPECIFIED
140+
def __init__( # pylint: disable=too-many-arguments
141+
self,
142+
component_id: int,
143+
timestamp: datetime,
144+
active_power: float = math.nan,
145+
current_per_phase: Tuple[float, float, float] | None = None,
146+
voltage_per_phase: Tuple[float, float, float] | None = None,
147+
cable_state: EVChargerCableState = EVChargerCableState.UNSPECIFIED,
148+
component_state: EVChargerComponentState = EVChargerComponentState.UNSPECIFIED,
149+
) -> None:
150+
"""Initialize the EvChargerDataWrapper.
151+
152+
This is a wrapper for the EvChargerData with default arguments. The parameters
153+
are documented in the EvChargerData class.
154+
"""
155+
super().__init__(
156+
component_id=component_id,
157+
timestamp=timestamp,
158+
active_power=active_power,
159+
current_per_phase=(
160+
current_per_phase
161+
if current_per_phase
162+
else (math.nan, math.nan, math.nan)
163+
),
164+
voltage_per_phase=(
165+
voltage_per_phase
166+
if voltage_per_phase
167+
else (math.nan, math.nan, math.nan)
168+
),
169+
cable_state=cable_state,
170+
component_state=component_state,
171+
)
107172

108173
def copy_with_new_timestamp(self, new_timestamp: datetime) -> EvChargerDataWrapper:
109174
"""Copy the component data but insert new timestamp.
@@ -124,14 +189,36 @@ def copy_with_new_timestamp(self, new_timestamp: datetime) -> EvChargerDataWrapp
124189
class MeterDataWrapper(MeterData):
125190
"""Wrapper for the MeterData with default arguments."""
126191

127-
active_power: float = math.nan
128-
current_per_phase: Tuple[float, float, float] = field(
129-
default_factory=lambda: (math.nan, math.nan, math.nan)
130-
)
131-
voltage_per_phase: Tuple[float, float, float] = field(
132-
default_factory=lambda: (math.nan, math.nan, math.nan)
133-
)
134-
frequency: float = math.nan
192+
def __init__( # pylint: disable=too-many-arguments
193+
self,
194+
component_id: int,
195+
timestamp: datetime,
196+
active_power: float = math.nan,
197+
current_per_phase: Tuple[float, float, float] | None = None,
198+
voltage_per_phase: Tuple[float, float, float] | None = None,
199+
frequency: float = math.nan,
200+
) -> None:
201+
"""Initialize the MeterDataWrapper.
202+
203+
This is a wrapper for the MeterData with default arguments. The parameters are
204+
documented in the MeterData class.
205+
"""
206+
super().__init__(
207+
component_id=component_id,
208+
timestamp=timestamp,
209+
active_power=active_power,
210+
current_per_phase=(
211+
current_per_phase
212+
if current_per_phase
213+
else (math.nan, math.nan, math.nan)
214+
),
215+
voltage_per_phase=(
216+
voltage_per_phase
217+
if voltage_per_phase
218+
else (math.nan, math.nan, math.nan)
219+
),
220+
frequency=frequency,
221+
)
135222

136223
def copy_with_new_timestamp(self, new_timestamp: datetime) -> MeterDataWrapper:
137224
"""Copy the component data but insert new timestamp.

0 commit comments

Comments
 (0)