shepherd-core 2025.10.1__py3-none-any.whl → 2026.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shepherd_core/config.py +1 -1
- shepherd_core/data_models/__init__.py +4 -2
- shepherd_core/data_models/base/cal_measurement.py +7 -2
- shepherd_core/data_models/base/calibration.py +23 -12
- shepherd_core/data_models/base/content.py +10 -2
- shepherd_core/data_models/base/shepherd.py +13 -4
- shepherd_core/data_models/base/wrapper.py +2 -0
- shepherd_core/data_models/content/__init__.py +4 -2
- shepherd_core/data_models/content/_external_fixtures.yaml +104 -96
- shepherd_core/data_models/content/_metadata_eenvs_bonito.yaml +436 -0
- shepherd_core/data_models/content/_metadata_eenvs_synthetic_multivariate_random_walk.yaml +164 -0
- shepherd_core/data_models/content/_metadata_eenvs_synthetic_on_off_markov.yaml +3280 -0
- shepherd_core/data_models/content/_metadata_eenvs_synthetic_on_off_windows.yaml +3260 -0
- shepherd_core/data_models/content/_metadata_eenvs_synthetic_static.yaml +450 -0
- shepherd_core/data_models/content/energy_environment.py +341 -23
- shepherd_core/data_models/content/energy_environment_fixture.yaml +21 -18
- shepherd_core/data_models/content/enum_datatypes.py +109 -0
- shepherd_core/data_models/content/firmware.py +44 -16
- shepherd_core/data_models/content/virtual_harvester_config.py +10 -93
- shepherd_core/data_models/content/virtual_source_config.py +21 -2
- shepherd_core/data_models/content/virtual_storage_config.py +7 -4
- shepherd_core/data_models/content/virtual_storage_fixture_creator.py +1 -1
- shepherd_core/data_models/content/virtual_storage_fixture_param_experiments.py +4 -4
- shepherd_core/data_models/experiment/experiment.py +38 -13
- shepherd_core/data_models/experiment/observer_features.py +17 -4
- shepherd_core/data_models/experiment/target_config.py +55 -7
- shepherd_core/data_models/task/__init__.py +13 -2
- shepherd_core/data_models/task/emulation.py +9 -5
- shepherd_core/data_models/task/firmware_mod.py +3 -1
- shepherd_core/data_models/task/harvest.py +2 -0
- shepherd_core/data_models/task/helper_paths.py +2 -2
- shepherd_core/data_models/task/observer_tasks.py +8 -6
- shepherd_core/data_models/task/programming.py +4 -2
- shepherd_core/data_models/task/testbed_tasks.py +8 -2
- shepherd_core/data_models/testbed/cape.py +2 -0
- shepherd_core/data_models/testbed/gpio.py +2 -0
- shepherd_core/data_models/testbed/mcu.py +2 -0
- shepherd_core/data_models/testbed/observer.py +2 -0
- shepherd_core/data_models/testbed/target.py +7 -5
- shepherd_core/data_models/testbed/target_fixture.old1 +1 -1
- shepherd_core/data_models/testbed/target_fixture.yaml +1 -1
- shepherd_core/data_models/testbed/testbed.py +17 -15
- shepherd_core/exit_handler.py +22 -0
- shepherd_core/fw_tools/converter.py +2 -2
- shepherd_core/fw_tools/validation.py +1 -1
- shepherd_core/inventory/__init__.py +23 -21
- shepherd_core/inventory/system.py +2 -2
- shepherd_core/logger.py +0 -1
- shepherd_core/reader.py +29 -25
- shepherd_core/testbed_client/cache_path.py +3 -3
- shepherd_core/testbed_client/client_abc_fix.py +14 -3
- shepherd_core/testbed_client/client_web.py +7 -5
- shepherd_core/testbed_client/fixtures.py +7 -7
- shepherd_core/version.py +1 -1
- shepherd_core/vsource/virtual_converter_model.py +2 -2
- shepherd_core/vsource/virtual_harvester_model.py +2 -2
- shepherd_core/vsource/virtual_harvester_simulation.py +5 -5
- shepherd_core/vsource/virtual_source_model.py +1 -1
- shepherd_core/vsource/virtual_source_simulation.py +9 -9
- shepherd_core/vsource/virtual_storage_models_kibam.py +3 -3
- shepherd_core/writer.py +16 -9
- {shepherd_core-2025.10.1.dist-info → shepherd_core-2026.2.1.dist-info}/METADATA +5 -3
- shepherd_core-2026.2.1.dist-info/RECORD +102 -0
- {shepherd_core-2025.10.1.dist-info → shepherd_core-2026.2.1.dist-info}/WHEEL +1 -1
- shepherd_core-2026.2.1.dist-info/licenses/LICENSE +21 -0
- shepherd_core/data_models/content/firmware_datatype.py +0 -15
- shepherd_core-2025.10.1.dist-info/RECORD +0 -95
- {shepherd_core-2025.10.1.dist-info → shepherd_core-2026.2.1.dist-info}/top_level.txt +0 -0
- {shepherd_core-2025.10.1.dist-info → shepherd_core-2026.2.1.dist-info}/zip-safe +0 -0
shepherd_core/config.py
CHANGED
|
@@ -27,7 +27,7 @@ class ConfigDefault(BaseModel):
|
|
|
27
27
|
UID_SIZE: int = 2
|
|
28
28
|
"""Variable size in Byte"""
|
|
29
29
|
|
|
30
|
-
TESTBED_SERVER: HttpUrl = "https://shepherd.cfaed.tu-dresden.de:8000/"
|
|
30
|
+
TESTBED_SERVER: HttpUrl = HttpUrl("https://shepherd.cfaed.tu-dresden.de:8000/")
|
|
31
31
|
"""Server that holds up to date testbed fixtures"""
|
|
32
32
|
|
|
33
33
|
|
|
@@ -18,10 +18,11 @@ from .base.calibration import CapeData
|
|
|
18
18
|
from .base.content import ContentModel
|
|
19
19
|
from .base.shepherd import ShpModel
|
|
20
20
|
from .base.wrapper import Wrapper
|
|
21
|
-
from .content.energy_environment import EnergyDType
|
|
22
21
|
from .content.energy_environment import EnergyEnvironment
|
|
22
|
+
from .content.energy_environment import EnergyProfile
|
|
23
|
+
from .content.enum_datatypes import EnergyDType
|
|
24
|
+
from .content.enum_datatypes import FirmwareDType
|
|
23
25
|
from .content.firmware import Firmware
|
|
24
|
-
from .content.firmware import FirmwareDType
|
|
25
26
|
from .content.virtual_harvester_config import VirtualHarvesterConfig
|
|
26
27
|
from .content.virtual_source_config import VirtualSourceConfig
|
|
27
28
|
from .content.virtual_storage_config import VirtualStorageConfig
|
|
@@ -45,6 +46,7 @@ __all__ = [
|
|
|
45
46
|
"ContentModel",
|
|
46
47
|
"EnergyDType",
|
|
47
48
|
"EnergyEnvironment",
|
|
49
|
+
"EnergyProfile",
|
|
48
50
|
"Experiment",
|
|
49
51
|
"Firmware",
|
|
50
52
|
"FirmwareDType",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Models for the process of calibration a device by measurements."""
|
|
2
2
|
|
|
3
3
|
from typing import Annotated
|
|
4
|
+
from typing import final
|
|
4
5
|
|
|
5
6
|
import numpy as np
|
|
6
7
|
from pydantic import Field
|
|
@@ -15,6 +16,7 @@ from .calibration import CapeData
|
|
|
15
16
|
from .shepherd import ShpModel
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
@final
|
|
18
20
|
class CalMeasurementPair(ShpModel):
|
|
19
21
|
"""Value-container for a calibration-measurement."""
|
|
20
22
|
|
|
@@ -39,8 +41,8 @@ def meas_to_cal(data: CalMeasPairs, component: str) -> CalibrationPair:
|
|
|
39
41
|
gain: float = float(model[0])
|
|
40
42
|
|
|
41
43
|
# r-squared, Pearson correlation coefficient
|
|
42
|
-
|
|
43
|
-
yhat =
|
|
44
|
+
pcoef = np.poly1d(model)
|
|
45
|
+
yhat = pcoef(x)
|
|
44
46
|
ybar: float = np.sum(y) / len(y)
|
|
45
47
|
ssreg: float = np.sum((yhat - ybar) ** 2)
|
|
46
48
|
sstot: float = np.sum((y - ybar) ** 2)
|
|
@@ -55,6 +57,7 @@ def meas_to_cal(data: CalMeasPairs, component: str) -> CalibrationPair:
|
|
|
55
57
|
return CalibrationPair(offset=offset, gain=gain)
|
|
56
58
|
|
|
57
59
|
|
|
60
|
+
@final
|
|
58
61
|
class CalMeasurementHarvester(ShpModel):
|
|
59
62
|
"""Container for the values of the calibration-measurement."""
|
|
60
63
|
|
|
@@ -71,6 +74,7 @@ class CalMeasurementHarvester(ShpModel):
|
|
|
71
74
|
return CalibrationHarvester(**dcal)
|
|
72
75
|
|
|
73
76
|
|
|
77
|
+
@final
|
|
74
78
|
class CalMeasurementEmulator(ShpModel):
|
|
75
79
|
"""Container for the values of the calibration-measurement."""
|
|
76
80
|
|
|
@@ -87,6 +91,7 @@ class CalMeasurementEmulator(ShpModel):
|
|
|
87
91
|
return CalibrationEmulator(**dcal)
|
|
88
92
|
|
|
89
93
|
|
|
94
|
+
@final
|
|
90
95
|
class CalMeasurementCape(ShpModel):
|
|
91
96
|
"""Container for the values of the calibration-measurement."""
|
|
92
97
|
|
|
@@ -5,14 +5,16 @@ from collections.abc import Callable
|
|
|
5
5
|
from collections.abc import Generator
|
|
6
6
|
from collections.abc import Mapping
|
|
7
7
|
from collections.abc import Sequence
|
|
8
|
+
from typing import Annotated
|
|
8
9
|
from typing import TypeVar
|
|
10
|
+
from typing import final
|
|
9
11
|
|
|
10
12
|
import numpy as np
|
|
11
13
|
from numpy.typing import NDArray
|
|
12
14
|
from pydantic import Field
|
|
13
15
|
from pydantic import PositiveFloat
|
|
16
|
+
from pydantic import StringConstraints
|
|
14
17
|
from pydantic import conbytes
|
|
15
|
-
from pydantic import constr
|
|
16
18
|
from pydantic import validate_call
|
|
17
19
|
from typing_extensions import Self
|
|
18
20
|
|
|
@@ -47,6 +49,7 @@ def dict_generator(
|
|
|
47
49
|
yield [*pre, in_dict]
|
|
48
50
|
|
|
49
51
|
|
|
52
|
+
@final
|
|
50
53
|
class CalibrationPair(ShpModel):
|
|
51
54
|
"""SI-value [SI-Unit] = raw-value * gain + offset."""
|
|
52
55
|
|
|
@@ -56,11 +59,11 @@ class CalibrationPair(ShpModel):
|
|
|
56
59
|
|
|
57
60
|
def raw_to_si(self, values_raw: Calc_t, *, allow_negative: bool = True) -> Calc_t:
|
|
58
61
|
"""Convert between physical units and raw unsigned integers."""
|
|
59
|
-
values_si =
|
|
62
|
+
values_si = self.gain * values_raw + self.offset
|
|
60
63
|
if not allow_negative:
|
|
61
64
|
if isinstance(values_si, np.ndarray):
|
|
62
65
|
values_si[values_si < 0.0] = 0.0
|
|
63
|
-
# if
|
|
66
|
+
# if type-checker still complains, cast with .astype(float)
|
|
64
67
|
else:
|
|
65
68
|
values_si = float(max(values_si, 0.0))
|
|
66
69
|
elif not isinstance(values_si, np.ndarray):
|
|
@@ -99,6 +102,7 @@ cal_pair_adc_V = CalibrationPair.from_fn(adc_voltage_to_raw, unit="V")
|
|
|
99
102
|
cal_pair_adc_C = CalibrationPair.from_fn(adc_current_to_raw, unit="A")
|
|
100
103
|
|
|
101
104
|
|
|
105
|
+
@final
|
|
102
106
|
class CalibrationHarvester(ShpModel):
|
|
103
107
|
"""Container for all calibration-pairs for that device."""
|
|
104
108
|
|
|
@@ -140,6 +144,7 @@ cal_emu_legacy = { # legacy translator
|
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
|
|
147
|
+
@final
|
|
143
148
|
class CalibrationEmulator(ShpModel):
|
|
144
149
|
"""Container for all calibration-pairs for that device.
|
|
145
150
|
|
|
@@ -177,6 +182,7 @@ class CalibrationEmulator(ShpModel):
|
|
|
177
182
|
return cal_set
|
|
178
183
|
|
|
179
184
|
|
|
185
|
+
@final
|
|
180
186
|
class CapeData(ShpModel):
|
|
181
187
|
"""Representation of Beaglebone Cape information.
|
|
182
188
|
|
|
@@ -190,15 +196,17 @@ class CapeData(ShpModel):
|
|
|
190
196
|
"""
|
|
191
197
|
|
|
192
198
|
header: conbytes(max_length=4) = b"\xaa\x55\x33\xee"
|
|
193
|
-
eeprom_revision:
|
|
194
|
-
board_name:
|
|
195
|
-
version:
|
|
196
|
-
manufacturer:
|
|
197
|
-
part_number:
|
|
199
|
+
eeprom_revision: Annotated[str, StringConstraints(max_length=2)] = "A2"
|
|
200
|
+
board_name: Annotated[str, StringConstraints(max_length=32)] = "BeagleBone SHEPHERD2 Cape"
|
|
201
|
+
version: Annotated[str, StringConstraints(max_length=4)] = "24B0"
|
|
202
|
+
manufacturer: Annotated[str, StringConstraints(max_length=16)] = "NES TU DRESDEN"
|
|
203
|
+
part_number: Annotated[str, StringConstraints(max_length=16)] = "BB-SHPRD"
|
|
198
204
|
|
|
199
|
-
serial_number:
|
|
205
|
+
serial_number: Annotated[str, StringConstraints(max_length=12)]
|
|
200
206
|
|
|
201
|
-
cal_date:
|
|
207
|
+
cal_date: Annotated[str, StringConstraints(max_length=12)] = Field(
|
|
208
|
+
default_factory=local_iso_date
|
|
209
|
+
)
|
|
202
210
|
# ⤷ produces something like '2023-01-01'
|
|
203
211
|
|
|
204
212
|
def __repr__(self) -> str: # TODO: override useful?
|
|
@@ -206,6 +214,7 @@ class CapeData(ShpModel):
|
|
|
206
214
|
return str(self.model_dump())
|
|
207
215
|
|
|
208
216
|
|
|
217
|
+
@final
|
|
209
218
|
class CalibrationCape(ShpModel):
|
|
210
219
|
"""Represents calibration data of shepherd cape.
|
|
211
220
|
|
|
@@ -231,6 +240,7 @@ class CalibrationCape(ShpModel):
|
|
|
231
240
|
----
|
|
232
241
|
data: Byte string containing calibration data.
|
|
233
242
|
cape: data can be supplied
|
|
243
|
+
|
|
234
244
|
Returns:
|
|
235
245
|
CalibrationCape object with extracted calibration data.
|
|
236
246
|
|
|
@@ -240,9 +250,9 @@ class CalibrationCape(ShpModel):
|
|
|
240
250
|
lw2 = [elem for elem in lw1 if isinstance(elem[-1], float)]
|
|
241
251
|
values = struct.unpack(">" + len(lw2) * "d", data)
|
|
242
252
|
# ⤷ X => double float, big endian
|
|
243
|
-
for
|
|
253
|
+
for i_, walk in enumerate(lw2):
|
|
244
254
|
# hardcoded fixed depth ... bad but easy
|
|
245
|
-
dv[walk[0]][walk[1]][walk[2]] = float(values[
|
|
255
|
+
dv[walk[0]][walk[1]][walk[2]] = float(values[i_])
|
|
246
256
|
dv["cape"] = cape
|
|
247
257
|
return cls(**dv)
|
|
248
258
|
|
|
@@ -260,6 +270,7 @@ class CalibrationCape(ShpModel):
|
|
|
260
270
|
return struct.pack(">" + len(values) * "d", *values)
|
|
261
271
|
|
|
262
272
|
|
|
273
|
+
@final
|
|
263
274
|
class CalibrationSeries(ShpModel):
|
|
264
275
|
"""Cal-Data for a typical recording of a testbed experiment."""
|
|
265
276
|
|
|
@@ -9,12 +9,15 @@ from pydantic import StringConstraints
|
|
|
9
9
|
from pydantic import model_validator
|
|
10
10
|
from typing_extensions import Self
|
|
11
11
|
|
|
12
|
+
from shepherd_core.logger import log
|
|
13
|
+
from shepherd_core.version import version as core_ver
|
|
14
|
+
|
|
12
15
|
from .shepherd import ShpModel
|
|
13
16
|
|
|
14
17
|
# constr -> to_lower=True, max_length=16, regex=r"^[\w]+$"
|
|
15
18
|
# ⤷ Regex = AlphaNum
|
|
16
19
|
IdInt = Annotated[int, Field(ge=0, lt=2**128)]
|
|
17
|
-
NameStr = Annotated[str, StringConstraints(max_length=
|
|
20
|
+
NameStr = Annotated[str, StringConstraints(max_length=50, pattern=r"^[^<>:;,?\"\*|\/\\]+$")]
|
|
18
21
|
# ⤷ Regex = FileSystem-Compatible ASCII
|
|
19
22
|
SafeStr = Annotated[str, StringConstraints(pattern=r"^[ -~]+$")]
|
|
20
23
|
# ⤷ Regex = All Printable ASCII-Characters with Space
|
|
@@ -41,6 +44,8 @@ class ContentModel(ShpModel):
|
|
|
41
44
|
comment: SafeStr | None = None
|
|
42
45
|
created: datetime = Field(default_factory=datetime.now)
|
|
43
46
|
updated_last: datetime = Field(default_factory=datetime.now)
|
|
47
|
+
deprecated: str | None = None
|
|
48
|
+
""" ⤷ deprecation-comments provoke a warning during validation of model."""
|
|
44
49
|
# TODO: add dedicated 'inherit_from' field?
|
|
45
50
|
|
|
46
51
|
# Ownership & Access
|
|
@@ -50,7 +55,8 @@ class ContentModel(ShpModel):
|
|
|
50
55
|
visible2group: bool = False
|
|
51
56
|
visible2all: bool = False
|
|
52
57
|
|
|
53
|
-
|
|
58
|
+
sw_ver: Annotated[str, Field(default=core_ver)]
|
|
59
|
+
""" ⤷ store core-version with content for compatibility management."""
|
|
54
60
|
|
|
55
61
|
def __str__(self) -> str:
|
|
56
62
|
return self.name
|
|
@@ -62,4 +68,6 @@ class ContentModel(ShpModel):
|
|
|
62
68
|
raise ValueError(
|
|
63
69
|
"Public instances require a description (check visible2*- and description-field)"
|
|
64
70
|
)
|
|
71
|
+
if isinstance(self.deprecated, str) and len(self.deprecated) > 0:
|
|
72
|
+
log.warning(f"Content {self.name} is deprecated: {self.deprecated}")
|
|
65
73
|
return self
|
|
@@ -8,6 +8,7 @@ from datetime import timedelta
|
|
|
8
8
|
from ipaddress import IPv4Address
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import Any
|
|
11
|
+
from typing import final
|
|
11
12
|
from uuid import UUID
|
|
12
13
|
|
|
13
14
|
import yaml
|
|
@@ -38,6 +39,7 @@ def generic2str(dumper: SafeDumper, data: Any) -> Node:
|
|
|
38
39
|
return dumper.represent_scalar("tag:yaml.org,2002:str", str(data))
|
|
39
40
|
|
|
40
41
|
|
|
42
|
+
# TODO: put in helper-file (similar to models/task/helper_paths.py) and make it callable
|
|
41
43
|
yaml.add_representer(pathlib.PosixPath, path2str, SafeDumper)
|
|
42
44
|
yaml.add_representer(pathlib.WindowsPath, path2str, SafeDumper)
|
|
43
45
|
yaml.add_representer(pathlib.Path, path2str, SafeDumper)
|
|
@@ -108,12 +110,15 @@ class ShpModel(BaseModel):
|
|
|
108
110
|
)
|
|
109
111
|
return str(content)
|
|
110
112
|
|
|
111
|
-
def __getitem__(self, key:
|
|
113
|
+
def __getitem__(self, key: Any) -> Any:
|
|
112
114
|
"""Allow dict access like model["key"].
|
|
113
115
|
|
|
114
116
|
in addition to model.key.
|
|
115
117
|
"""
|
|
116
|
-
|
|
118
|
+
if isinstance(key, str):
|
|
119
|
+
return self.__getattribute__(key)
|
|
120
|
+
msg = f"Unknown key '{key}' used when selecting from Model."
|
|
121
|
+
raise IndexError(msg)
|
|
117
122
|
|
|
118
123
|
def __contains__(self, item: str) -> bool:
|
|
119
124
|
"""Allow checks like 'x in YClass'."""
|
|
@@ -127,8 +132,9 @@ class ShpModel(BaseModel):
|
|
|
127
132
|
def items(self) -> Generator[tuple, None, None]:
|
|
128
133
|
"""Fn of dict."""
|
|
129
134
|
for key in self.keys():
|
|
130
|
-
yield key, self
|
|
135
|
+
yield key, self.__getattribute__(key)
|
|
131
136
|
|
|
137
|
+
@final
|
|
132
138
|
@classmethod
|
|
133
139
|
def schema_to_file(cls, path: str | Path) -> None:
|
|
134
140
|
"""Store schema to yaml (for frontend-generators)."""
|
|
@@ -137,6 +143,7 @@ class ShpModel(BaseModel):
|
|
|
137
143
|
with Path(path).resolve().with_suffix(".yaml").open("w") as f:
|
|
138
144
|
f.write(model_yaml)
|
|
139
145
|
|
|
146
|
+
@final
|
|
140
147
|
def to_file(
|
|
141
148
|
self,
|
|
142
149
|
path: str | Path,
|
|
@@ -178,6 +185,7 @@ class ShpModel(BaseModel):
|
|
|
178
185
|
f.write(model_serial)
|
|
179
186
|
return model_path
|
|
180
187
|
|
|
188
|
+
@final
|
|
181
189
|
@classmethod
|
|
182
190
|
def from_file(cls, path: str | Path) -> Self:
|
|
183
191
|
"""Load from YAML or pickle file."""
|
|
@@ -188,12 +196,13 @@ class ShpModel(BaseModel):
|
|
|
188
196
|
with Path(path).open("rb") as shp_file:
|
|
189
197
|
shp_dict = pickle.load(shp_file) # noqa: S301
|
|
190
198
|
else:
|
|
191
|
-
with Path(path).open() as shp_file:
|
|
199
|
+
with Path(path).open(encoding="utf-8-sig") as shp_file:
|
|
192
200
|
shp_dict = yaml.safe_load(shp_file)
|
|
193
201
|
shp_wrap = Wrapper(**shp_dict)
|
|
194
202
|
if shp_wrap.datatype != cls.__name__:
|
|
195
203
|
raise ValueError("Model in file does not match the actual Class")
|
|
196
204
|
return cls(**shp_wrap.parameters)
|
|
197
205
|
|
|
206
|
+
@final
|
|
198
207
|
def get_hash(self) -> str:
|
|
199
208
|
return hashlib.sha3_224(str(self.model_dump()).encode("utf-8")).hexdigest()
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from typing import Annotated
|
|
5
|
+
from typing import final
|
|
5
6
|
|
|
6
7
|
from pydantic import BaseModel
|
|
7
8
|
from pydantic import StringConstraints
|
|
@@ -12,6 +13,7 @@ SafeStrClone = Annotated[str, StringConstraints(pattern=r"^[ -~]+$")]
|
|
|
12
13
|
# ⤷ copy avoids circular import
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
@final
|
|
15
17
|
class Wrapper(BaseModel):
|
|
16
18
|
"""Generalized web- & file-interface for all models with dynamic typecasting."""
|
|
17
19
|
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
These models import externally from: /base, /testbed.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from .energy_environment import EnergyDType
|
|
7
6
|
from .energy_environment import EnergyEnvironment
|
|
7
|
+
from .energy_environment import EnergyProfile
|
|
8
|
+
from .enum_datatypes import EnergyDType
|
|
9
|
+
from .enum_datatypes import FirmwareDType
|
|
8
10
|
from .firmware import Firmware
|
|
9
|
-
from .firmware_datatype import FirmwareDType
|
|
10
11
|
from .virtual_harvester_config import VirtualHarvesterConfig
|
|
11
12
|
from .virtual_source_config import VirtualSourceConfig
|
|
12
13
|
from .virtual_storage_config import VirtualStorageConfig
|
|
@@ -14,6 +15,7 @@ from .virtual_storage_config import VirtualStorageConfig
|
|
|
14
15
|
__all__ = [
|
|
15
16
|
"EnergyDType",
|
|
16
17
|
"EnergyEnvironment",
|
|
18
|
+
"EnergyProfile",
|
|
17
19
|
"Firmware",
|
|
18
20
|
"FirmwareDType",
|
|
19
21
|
"VirtualHarvesterConfig",
|