shepherd-core 2023.12.1__py3-none-any.whl → 2024.4.2__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/__init__.py +5 -4
- shepherd_core/calibration_hw_def.py +9 -1
- shepherd_core/commons.py +2 -0
- shepherd_core/data_models/__init__.py +11 -0
- shepherd_core/data_models/base/__init__.py +4 -1
- shepherd_core/data_models/base/cal_measurement.py +18 -6
- shepherd_core/data_models/base/calibration.py +41 -16
- shepherd_core/data_models/base/content.py +20 -5
- shepherd_core/data_models/base/shepherd.py +23 -12
- shepherd_core/data_models/base/timezone.py +5 -0
- shepherd_core/data_models/base/wrapper.py +3 -3
- shepherd_core/data_models/content/__init__.py +5 -4
- shepherd_core/data_models/content/_external_fixtures.yaml +32 -16
- shepherd_core/data_models/content/energy_environment.py +7 -5
- shepherd_core/data_models/content/energy_environment_fixture.yaml +3 -0
- shepherd_core/data_models/content/firmware.py +12 -5
- shepherd_core/data_models/content/firmware_datatype.py +7 -0
- shepherd_core/data_models/content/virtual_harvester.py +25 -20
- shepherd_core/data_models/content/virtual_harvester_fixture.yaml +1 -0
- shepherd_core/data_models/content/virtual_source.py +40 -23
- shepherd_core/data_models/content/virtual_source_fixture.yaml +1 -0
- shepherd_core/data_models/experiment/__init__.py +5 -4
- shepherd_core/data_models/experiment/experiment.py +16 -15
- shepherd_core/data_models/experiment/observer_features.py +18 -12
- shepherd_core/data_models/experiment/target_config.py +11 -7
- shepherd_core/data_models/readme.md +88 -0
- shepherd_core/data_models/task/__init__.py +10 -3
- shepherd_core/data_models/task/emulation.py +9 -6
- shepherd_core/data_models/task/firmware_mod.py +4 -2
- shepherd_core/data_models/task/harvest.py +5 -4
- shepherd_core/data_models/task/observer_tasks.py +4 -2
- shepherd_core/data_models/task/programming.py +3 -1
- shepherd_core/data_models/task/testbed_tasks.py +10 -4
- shepherd_core/data_models/testbed/__init__.py +5 -2
- shepherd_core/data_models/testbed/cape.py +8 -6
- shepherd_core/data_models/testbed/gpio.py +11 -9
- shepherd_core/data_models/testbed/mcu.py +10 -10
- shepherd_core/data_models/testbed/observer.py +10 -5
- shepherd_core/data_models/testbed/observer_fixture.yaml +23 -22
- shepherd_core/data_models/testbed/target.py +5 -3
- shepherd_core/data_models/testbed/target_fixture.yaml +11 -11
- shepherd_core/data_models/testbed/testbed.py +6 -3
- shepherd_core/decoder_waveform/__init__.py +2 -0
- shepherd_core/decoder_waveform/uart.py +44 -25
- shepherd_core/fw_tools/__init__.py +2 -0
- shepherd_core/fw_tools/converter.py +20 -9
- shepherd_core/fw_tools/converter_elf.py +3 -0
- shepherd_core/fw_tools/patcher.py +16 -4
- shepherd_core/fw_tools/validation.py +25 -5
- shepherd_core/inventory/__init__.py +66 -6
- shepherd_core/inventory/python.py +4 -0
- shepherd_core/inventory/system.py +13 -1
- shepherd_core/inventory/target.py +4 -0
- shepherd_core/logger.py +5 -0
- shepherd_core/reader.py +44 -26
- shepherd_core/testbed_client/__init__.py +2 -0
- shepherd_core/testbed_client/cache_path.py +17 -0
- shepherd_core/testbed_client/client.py +14 -8
- shepherd_core/testbed_client/fixtures.py +30 -11
- shepherd_core/testbed_client/user_model.py +13 -6
- shepherd_core/vsource/__init__.py +2 -0
- shepherd_core/vsource/virtual_converter_model.py +11 -4
- shepherd_core/vsource/virtual_harvester_model.py +8 -1
- shepherd_core/vsource/virtual_source_model.py +10 -5
- shepherd_core/writer.py +28 -20
- {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/METADATA +50 -34
- shepherd_core-2024.4.2.dist-info/RECORD +75 -0
- {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/WHEEL +1 -1
- {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/top_level.txt +0 -1
- shepherd_core-2023.12.1.dist-info/RECORD +0 -117
- tests/__init__.py +0 -0
- tests/conftest.py +0 -64
- tests/data_models/__init__.py +0 -0
- tests/data_models/conftest.py +0 -14
- tests/data_models/example_cal_data.yaml +0 -31
- tests/data_models/example_cal_data_faulty.yaml +0 -29
- tests/data_models/example_cal_meas.yaml +0 -178
- tests/data_models/example_cal_meas_faulty1.yaml +0 -142
- tests/data_models/example_cal_meas_faulty2.yaml +0 -136
- tests/data_models/example_config_emulator.yaml +0 -41
- tests/data_models/example_config_experiment.yaml +0 -16
- tests/data_models/example_config_experiment_alternative.yaml +0 -14
- tests/data_models/example_config_harvester.yaml +0 -15
- tests/data_models/example_config_testbed.yaml +0 -26
- tests/data_models/example_config_virtsource.yaml +0 -78
- tests/data_models/test_base_models.py +0 -205
- tests/data_models/test_content_fixtures.py +0 -41
- tests/data_models/test_content_models.py +0 -282
- tests/data_models/test_examples.py +0 -48
- tests/data_models/test_experiment_models.py +0 -277
- tests/data_models/test_task_generation.py +0 -52
- tests/data_models/test_task_models.py +0 -131
- tests/data_models/test_testbed_fixtures.py +0 -47
- tests/data_models/test_testbed_models.py +0 -187
- tests/decoder_waveform/__init__.py +0 -0
- tests/decoder_waveform/test_decoder.py +0 -34
- tests/fw_tools/__init__.py +0 -0
- tests/fw_tools/conftest.py +0 -5
- tests/fw_tools/test_converter.py +0 -76
- tests/fw_tools/test_patcher.py +0 -66
- tests/fw_tools/test_validation.py +0 -56
- tests/inventory/__init__.py +0 -0
- tests/inventory/test_inventory.py +0 -20
- tests/test_cal_hw.py +0 -34
- tests/test_examples.py +0 -40
- tests/test_logger.py +0 -15
- tests/test_reader.py +0 -283
- tests/test_writer.py +0 -169
- tests/testbed_client/__init__.py +0 -0
- tests/vsource/__init__.py +0 -0
- tests/vsource/conftest.py +0 -49
- tests/vsource/test_converter.py +0 -161
- tests/vsource/test_harvester.py +0 -73
- tests/vsource/test_z.py +0 -5
- /shepherd_core/data_models/{doc_virtual_source.py → virtual_source_doc.txt} +0 -0
- {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/zip-safe +0 -0
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
from shepherd_core.data_models.content.energy_environment import EnergyEnvironment
|
|
2
|
-
from shepherd_core.data_models.content.firmware import Firmware
|
|
3
|
-
from shepherd_core.data_models.content.virtual_harvester import HarvesterPRUConfig
|
|
4
|
-
from shepherd_core.data_models.content.virtual_harvester import VirtualHarvesterConfig
|
|
5
|
-
from shepherd_core.data_models.content.virtual_source import ConverterPRUConfig
|
|
6
|
-
from shepherd_core.data_models.content.virtual_source import VirtualSourceConfig
|
|
7
|
-
from shepherd_core.testbed_client.fixtures import Fixtures
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def test_testbed_fixture_energy_environment() -> None:
|
|
11
|
-
for fix in Fixtures()["EnergyEnvironment"]:
|
|
12
|
-
EnergyEnvironment(name=fix["name"])
|
|
13
|
-
EnergyEnvironment(id=fix["id"])
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def test_testbed_fixture_firmware() -> None:
|
|
17
|
-
for fix in Fixtures()["Firmware"]:
|
|
18
|
-
_id = fix["id"]
|
|
19
|
-
if _id in {1001, 1002}:
|
|
20
|
-
continue
|
|
21
|
-
Firmware(name=fix["name"])
|
|
22
|
-
Firmware(id=fix["id"])
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def test_experiment_fixture_vsrc() -> None:
|
|
26
|
-
for fix in Fixtures()["VirtualSourceConfig"]:
|
|
27
|
-
vsrc = VirtualSourceConfig(name=fix["name"])
|
|
28
|
-
VirtualSourceConfig(id=fix["id"])
|
|
29
|
-
ConverterPRUConfig.from_vsrc(vsrc, log_intermediate_node=False)
|
|
30
|
-
ConverterPRUConfig.from_vsrc(vsrc, log_intermediate_node=True)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def test_experiment_fixture_vhrv() -> None:
|
|
34
|
-
for fix in Fixtures()["VirtualHarvesterConfig"]:
|
|
35
|
-
if fix["name"] == "neutral":
|
|
36
|
-
continue
|
|
37
|
-
vhrv = VirtualHarvesterConfig(name=fix["name"])
|
|
38
|
-
VirtualHarvesterConfig(id=fix["id"])
|
|
39
|
-
HarvesterPRUConfig.from_vhrv(vhrv, for_emu=False)
|
|
40
|
-
if int(fix["id"]) >= 1030:
|
|
41
|
-
HarvesterPRUConfig.from_vhrv(vhrv, for_emu=True)
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
from pydantic import ValidationError
|
|
5
|
-
|
|
6
|
-
from shepherd_core import fw_tools
|
|
7
|
-
from shepherd_core.data_models.content import EnergyDType
|
|
8
|
-
from shepherd_core.data_models.content import EnergyEnvironment
|
|
9
|
-
from shepherd_core.data_models.content import Firmware
|
|
10
|
-
from shepherd_core.data_models.content import FirmwareDType
|
|
11
|
-
from shepherd_core.data_models.content import VirtualHarvesterConfig
|
|
12
|
-
from shepherd_core.data_models.content import VirtualSourceConfig
|
|
13
|
-
from shepherd_core.data_models.content.virtual_source import ConverterPRUConfig
|
|
14
|
-
from shepherd_core.data_models.testbed import MCU
|
|
15
|
-
|
|
16
|
-
from .conftest import files_elf
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def test_content_model_ee_min1() -> None:
|
|
20
|
-
EnergyEnvironment(
|
|
21
|
-
id=9999,
|
|
22
|
-
name="some",
|
|
23
|
-
data_path="./file",
|
|
24
|
-
data_type="isc_voc",
|
|
25
|
-
duration=1,
|
|
26
|
-
energy_Ws=0.1,
|
|
27
|
-
owner="jane",
|
|
28
|
-
group="wayne",
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def test_content_model_ee_min2() -> None:
|
|
33
|
-
EnergyEnvironment(
|
|
34
|
-
id="98765",
|
|
35
|
-
name="some",
|
|
36
|
-
data_path="./file",
|
|
37
|
-
data_type=EnergyDType.ivcurve,
|
|
38
|
-
duration=999,
|
|
39
|
-
energy_Ws=3.1,
|
|
40
|
-
owner="jane",
|
|
41
|
-
group="wayne",
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def test_content_model_fw_faulty() -> None:
|
|
46
|
-
with pytest.raises(ValueError):
|
|
47
|
-
Firmware(
|
|
48
|
-
id=9999,
|
|
49
|
-
name="dome",
|
|
50
|
-
mcu=MCU(name="nRF52"),
|
|
51
|
-
data="xyz",
|
|
52
|
-
data_type=FirmwareDType.base64_hex,
|
|
53
|
-
owner="Obelix",
|
|
54
|
-
group="Gaul",
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@pytest.mark.elf
|
|
59
|
-
@pytest.mark.converter
|
|
60
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
61
|
-
def test_content_model_fw_min(path_elf: Path, tmp_path: Path) -> None:
|
|
62
|
-
path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
|
|
63
|
-
path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
|
|
64
|
-
Firmware(
|
|
65
|
-
id=9999,
|
|
66
|
-
name="dome",
|
|
67
|
-
mcu=MCU(name="nRF52"),
|
|
68
|
-
data=fw_tools.file_to_base64(path_hex),
|
|
69
|
-
data_type=FirmwareDType.base64_hex,
|
|
70
|
-
owner="Obelix",
|
|
71
|
-
group="Gaul",
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
@pytest.mark.elf
|
|
76
|
-
@pytest.mark.converter
|
|
77
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
78
|
-
def test_content_model_fw_from_elf(path_elf: Path) -> None:
|
|
79
|
-
Firmware.from_firmware(
|
|
80
|
-
file=path_elf,
|
|
81
|
-
name="dome",
|
|
82
|
-
owner="Obelix",
|
|
83
|
-
group="Gaul",
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@pytest.mark.elf
|
|
88
|
-
@pytest.mark.converter
|
|
89
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
90
|
-
def test_content_model_fw_from_hex(path_elf: Path, tmp_path: Path) -> None:
|
|
91
|
-
path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
|
|
92
|
-
path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
|
|
93
|
-
Firmware.from_firmware(
|
|
94
|
-
file=path_hex,
|
|
95
|
-
name="dome",
|
|
96
|
-
owner="Obelix",
|
|
97
|
-
group="Gaul",
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def test_content_model_fw_from_hex_failing(tmp_path: Path) -> None:
|
|
102
|
-
path_hex = tmp_path / "some.hex"
|
|
103
|
-
with path_hex.open("w") as fd:
|
|
104
|
-
fd.write("something")
|
|
105
|
-
with pytest.raises(ValueError):
|
|
106
|
-
Firmware.from_firmware(
|
|
107
|
-
file=path_hex,
|
|
108
|
-
name="dome",
|
|
109
|
-
owner="Obelix",
|
|
110
|
-
group="Gaul",
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
@pytest.mark.elf
|
|
115
|
-
@pytest.mark.converter
|
|
116
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
117
|
-
def test_content_model_fw_extract_elf_to_dir(path_elf: Path, tmp_path: Path) -> None:
|
|
118
|
-
fw = Firmware.from_firmware(
|
|
119
|
-
file=path_elf,
|
|
120
|
-
name="dome",
|
|
121
|
-
owner="Obelix",
|
|
122
|
-
group="Gaul",
|
|
123
|
-
)
|
|
124
|
-
file = fw.extract_firmware(tmp_path)
|
|
125
|
-
assert file.exists()
|
|
126
|
-
assert file.is_file()
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@pytest.mark.elf
|
|
130
|
-
@pytest.mark.converter
|
|
131
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
132
|
-
def test_content_model_fw_extract_hex_to_dir(path_elf: Path, tmp_path: Path) -> None:
|
|
133
|
-
path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
|
|
134
|
-
path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
|
|
135
|
-
fw = Firmware.from_firmware(
|
|
136
|
-
file=path_hex,
|
|
137
|
-
name="dome",
|
|
138
|
-
owner="Obelix",
|
|
139
|
-
group="Gaul",
|
|
140
|
-
)
|
|
141
|
-
file = fw.extract_firmware(tmp_path)
|
|
142
|
-
assert file.exists()
|
|
143
|
-
assert file.is_file()
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
147
|
-
def test_content_model_fw_extract_path_elf_to_dir(path_elf: Path, tmp_path: Path) -> None:
|
|
148
|
-
assert path_elf.exists()
|
|
149
|
-
fw = Firmware(
|
|
150
|
-
data=path_elf,
|
|
151
|
-
data_type=FirmwareDType.path_elf,
|
|
152
|
-
mcu={"name": "MSP430FR"},
|
|
153
|
-
name="dome",
|
|
154
|
-
owner="Obelix",
|
|
155
|
-
group="Gaul",
|
|
156
|
-
)
|
|
157
|
-
file = fw.extract_firmware(tmp_path)
|
|
158
|
-
assert file.exists()
|
|
159
|
-
assert file.is_file()
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
@pytest.mark.elf
|
|
163
|
-
@pytest.mark.converter
|
|
164
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
165
|
-
def test_content_model_fw_extract_path_hex_to_dir(path_elf: Path, tmp_path: Path) -> None:
|
|
166
|
-
path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
|
|
167
|
-
path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
|
|
168
|
-
assert path_hex.exists()
|
|
169
|
-
fw = Firmware(
|
|
170
|
-
data=path_hex,
|
|
171
|
-
data_type=FirmwareDType.path_hex,
|
|
172
|
-
mcu={"name": "MSP430FR"},
|
|
173
|
-
name="dome",
|
|
174
|
-
owner="Obelix",
|
|
175
|
-
group="Gaul",
|
|
176
|
-
)
|
|
177
|
-
file = fw.extract_firmware(tmp_path)
|
|
178
|
-
assert file.exists()
|
|
179
|
-
assert file.is_file()
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
def test_content_model_hrv_min() -> None:
|
|
183
|
-
hrv = VirtualHarvesterConfig(
|
|
184
|
-
id=9999,
|
|
185
|
-
name="whatever",
|
|
186
|
-
owner="jane",
|
|
187
|
-
group="wayne",
|
|
188
|
-
algorithm="mppt_opt",
|
|
189
|
-
)
|
|
190
|
-
assert hrv.get_datatype() == "ivsample"
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
def test_content_model_hrv_neutral() -> None:
|
|
194
|
-
with pytest.raises(ValueError):
|
|
195
|
-
_ = VirtualHarvesterConfig(name="neutral")
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
@pytest.mark.parametrize("name", ["iv110", "cv24", "mppt_voc", "mppt_po"])
|
|
199
|
-
def test_content_model_hrv_by_name(name: str) -> None:
|
|
200
|
-
_ = VirtualHarvesterConfig(name=name)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
@pytest.mark.parametrize("uid", [1013, 1020, 1032, 1044, 1045, 1046])
|
|
204
|
-
def test_content_model_hrv_by_id(uid: int) -> None:
|
|
205
|
-
_ = VirtualHarvesterConfig(id=uid)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
def test_content_model_hrv_steps() -> None:
|
|
209
|
-
hrv = VirtualHarvesterConfig(
|
|
210
|
-
name="ivcurves", voltage_min_mV=1000, voltage_max_mV=4000, samples_n=11
|
|
211
|
-
)
|
|
212
|
-
assert hrv.voltage_step_mV == 300
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
def test_content_model_hrv_faulty_voltage0() -> None:
|
|
216
|
-
with pytest.raises(ValidationError):
|
|
217
|
-
_ = VirtualHarvesterConfig(name="iv110", voltage_max_mV=5001)
|
|
218
|
-
with pytest.raises(ValidationError):
|
|
219
|
-
_ = VirtualHarvesterConfig(name="iv110", voltage_min_mV=-1)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
def test_content_model_hrv_faulty_voltage1() -> None:
|
|
223
|
-
with pytest.raises(ValueError):
|
|
224
|
-
_ = VirtualHarvesterConfig(name="iv110", voltage_min_mV=4001, voltage_max_mV=4000)
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
def test_content_model_hrv_faulty_voltage2() -> None:
|
|
228
|
-
with pytest.raises(ValueError):
|
|
229
|
-
_ = VirtualHarvesterConfig(name="iv110", voltage_mV=4001, voltage_max_mV=4000)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
def test_content_model_hrv_faulty_voltage3() -> None:
|
|
233
|
-
with pytest.raises(ValueError):
|
|
234
|
-
_ = VirtualHarvesterConfig(name="iv110", voltage_mV=4000, voltage_min_mV=4001)
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
@pytest.mark.parametrize("name", ["ivcurves", "iv1000", "isc_voc"])
|
|
238
|
-
def test_content_model_hrv_faulty_emu(name: str) -> None:
|
|
239
|
-
hrv = VirtualHarvesterConfig(name=name)
|
|
240
|
-
with pytest.raises(ValueError):
|
|
241
|
-
_ = VirtualSourceConfig(name="dio_cap", harvester=hrv)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
def test_content_model_src_min() -> None:
|
|
245
|
-
VirtualSourceConfig(
|
|
246
|
-
id=9999,
|
|
247
|
-
name="new_src",
|
|
248
|
-
owner="jane",
|
|
249
|
-
group="wayne",
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
def test_content_model_src_force_warning() -> None:
|
|
254
|
-
src = VirtualSourceConfig(
|
|
255
|
-
name="BQ25570",
|
|
256
|
-
C_output_uF=200,
|
|
257
|
-
C_intermediate_uF=100,
|
|
258
|
-
)
|
|
259
|
-
ConverterPRUConfig.from_vsrc(src)
|
|
260
|
-
# -> triggers warning currently
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
def test_content_model_src_force_other_hysteresis1() -> None:
|
|
264
|
-
src = VirtualSourceConfig(
|
|
265
|
-
name="BQ25570",
|
|
266
|
-
V_intermediate_enable_threshold_mV=4000,
|
|
267
|
-
V_intermediate_disable_threshold_mV=3999,
|
|
268
|
-
V_output_mV=2000,
|
|
269
|
-
V_buck_drop_mV=100,
|
|
270
|
-
)
|
|
271
|
-
ConverterPRUConfig.from_vsrc(src)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
def test_content_model_src_force_other_hysteresis2() -> None:
|
|
275
|
-
src = VirtualSourceConfig(
|
|
276
|
-
name="BQ25570",
|
|
277
|
-
V_intermediate_enable_threshold_mV=1000,
|
|
278
|
-
V_intermediate_disable_threshold_mV=999,
|
|
279
|
-
V_output_mV=2000,
|
|
280
|
-
V_buck_drop_mV=100,
|
|
281
|
-
)
|
|
282
|
-
ConverterPRUConfig.from_vsrc(src)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from shepherd_core.data_models.content import VirtualSourceConfig
|
|
4
|
-
from shepherd_core.data_models.experiment import Experiment
|
|
5
|
-
from shepherd_core.data_models.task import EmulationTask
|
|
6
|
-
from shepherd_core.data_models.task import HarvestTask
|
|
7
|
-
from shepherd_core.data_models.testbed.testbed import Testbed as TasteBad
|
|
8
|
-
|
|
9
|
-
from .conftest import load_yaml
|
|
10
|
-
|
|
11
|
-
# ⤷ TasteBad avoids pytest-warning
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def test_example_emu() -> None:
|
|
15
|
-
data_dict = load_yaml("example_config_emulator.yaml")
|
|
16
|
-
assert data_dict["mode"] == "emulator"
|
|
17
|
-
emu = EmulationTask(**data_dict["parameters"])
|
|
18
|
-
print(emu)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def test_example_hrv() -> None:
|
|
22
|
-
data_dict = load_yaml("example_config_harvester.yaml")
|
|
23
|
-
assert data_dict["mode"] == "harvester"
|
|
24
|
-
emu = HarvestTask(**data_dict["parameters"])
|
|
25
|
-
print(emu)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def test_example_exp_recommended() -> None:
|
|
29
|
-
# new way
|
|
30
|
-
path = Path(__file__).with_name("example_config_experiment.yaml")
|
|
31
|
-
Experiment.from_file(path)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def test_example_exp() -> None:
|
|
35
|
-
# non-optimal / old way
|
|
36
|
-
data_dict = load_yaml("example_config_experiment_alternative.yaml")
|
|
37
|
-
Experiment(**data_dict)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def test_example_tb() -> None:
|
|
41
|
-
data_dict = load_yaml("example_config_testbed.yaml")
|
|
42
|
-
print(data_dict)
|
|
43
|
-
TasteBad(**data_dict)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def test_example_vsrc() -> None:
|
|
47
|
-
data_dict = load_yaml("example_config_virtsource.yaml")
|
|
48
|
-
VirtualSourceConfig(**data_dict["VirtualSource"])
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
from datetime import timedelta
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
from pydantic import ValidationError
|
|
5
|
-
|
|
6
|
-
from shepherd_core import local_now
|
|
7
|
-
from shepherd_core.data_models import VirtualHarvesterConfig
|
|
8
|
-
from shepherd_core.data_models import VirtualSourceConfig
|
|
9
|
-
from shepherd_core.data_models.content import EnergyEnvironment
|
|
10
|
-
from shepherd_core.data_models.content import Firmware
|
|
11
|
-
from shepherd_core.data_models.experiment import Experiment
|
|
12
|
-
from shepherd_core.data_models.experiment import GpioActuation
|
|
13
|
-
from shepherd_core.data_models.experiment import GpioEvent
|
|
14
|
-
from shepherd_core.data_models.experiment import GpioLevel
|
|
15
|
-
from shepherd_core.data_models.experiment import GpioTracing
|
|
16
|
-
from shepherd_core.data_models.experiment import PowerTracing
|
|
17
|
-
from shepherd_core.data_models.experiment import SystemLogging
|
|
18
|
-
from shepherd_core.data_models.experiment import TargetConfig
|
|
19
|
-
from shepherd_core.data_models.testbed import GPIO
|
|
20
|
-
from shepherd_core.data_models.testbed import Target
|
|
21
|
-
|
|
22
|
-
from .conftest import load_yaml
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def test_experiment_model_exp_min() -> None:
|
|
26
|
-
Experiment(
|
|
27
|
-
name="mex per",
|
|
28
|
-
target_configs=[
|
|
29
|
-
TargetConfig(
|
|
30
|
-
target_IDs=[1],
|
|
31
|
-
energy_env=EnergyEnvironment(name="SolarSunny"),
|
|
32
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
33
|
-
)
|
|
34
|
-
],
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def test_experiment_model_exp_yaml_load() -> None:
|
|
39
|
-
exp1_data = load_yaml("example_config_experiment_alternative.yaml")
|
|
40
|
-
Experiment(**exp1_data)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def test_experiment_model_exp_yaml_comparison() -> None:
|
|
44
|
-
exp1_data = load_yaml("example_config_experiment_alternative.yaml")
|
|
45
|
-
exp1 = Experiment(**exp1_data)
|
|
46
|
-
|
|
47
|
-
target_cfgs = TargetConfig(
|
|
48
|
-
target_IDs=list(range(1, 5)),
|
|
49
|
-
custom_IDs=list(range(4)),
|
|
50
|
-
energy_env={"name": "SolarSunny"},
|
|
51
|
-
virtual_source={"name": "diode+capacitor"},
|
|
52
|
-
firmware1={"name": "nrf52_demo_rf"},
|
|
53
|
-
)
|
|
54
|
-
exp2 = Experiment(
|
|
55
|
-
id=4567,
|
|
56
|
-
name="meaningful Test-Name",
|
|
57
|
-
created="2023-11-11 11:11:11",
|
|
58
|
-
time_start="2023-12-12 12:12:12",
|
|
59
|
-
target_configs=[target_cfgs],
|
|
60
|
-
)
|
|
61
|
-
assert exp1.get_hash() == exp2.get_hash()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def test_experiment_model_exp_collision_target_id() -> None:
|
|
65
|
-
hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
|
|
66
|
-
target_cfgs = [
|
|
67
|
-
TargetConfig(
|
|
68
|
-
target_IDs=[1, 2, 3], # <- collision
|
|
69
|
-
custom_IDs=[0, 1, 2, 3],
|
|
70
|
-
energy_env={"name": "SolarSunny"},
|
|
71
|
-
virtual_source={"name": "diode+capacitor"},
|
|
72
|
-
firmware1={"name": "nrf52_demo_rf"},
|
|
73
|
-
),
|
|
74
|
-
TargetConfig(
|
|
75
|
-
target_IDs=list(range(1, 5)), # <- collision
|
|
76
|
-
custom_IDs=list(range(7, 18)), # note: longer list is OK
|
|
77
|
-
energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
|
|
78
|
-
virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
|
|
79
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
80
|
-
firmware2=Firmware(name="msp430_deep_sleep"),
|
|
81
|
-
),
|
|
82
|
-
]
|
|
83
|
-
with pytest.raises(ValueError):
|
|
84
|
-
_ = Experiment(
|
|
85
|
-
id="4567",
|
|
86
|
-
name="meaningful Test-Name",
|
|
87
|
-
time_start=local_now() + timedelta(minutes=30),
|
|
88
|
-
target_configs=target_cfgs,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def test_experiment_model_exp_collision_custom_id() -> None:
|
|
93
|
-
hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
|
|
94
|
-
target_cfgs = [
|
|
95
|
-
TargetConfig(
|
|
96
|
-
target_IDs=[1, 2, 3],
|
|
97
|
-
custom_IDs=[0, 1, 7], # <- collision
|
|
98
|
-
energy_env={"name": "SolarSunny"},
|
|
99
|
-
virtual_source={"name": "diode+capacitor"},
|
|
100
|
-
firmware1={"name": "nrf52_demo_rf"},
|
|
101
|
-
),
|
|
102
|
-
TargetConfig(
|
|
103
|
-
target_IDs=list(range(1, 5)),
|
|
104
|
-
custom_IDs=list(range(7, 18)), # <- collision
|
|
105
|
-
energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
|
|
106
|
-
virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
|
|
107
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
108
|
-
firmware2=Firmware(name="msp430_deep_sleep"),
|
|
109
|
-
),
|
|
110
|
-
]
|
|
111
|
-
with pytest.raises(ValueError):
|
|
112
|
-
_ = Experiment(
|
|
113
|
-
id="4567",
|
|
114
|
-
name="meaningful Test-Name",
|
|
115
|
-
time_start=local_now() + timedelta(minutes=30),
|
|
116
|
-
target_configs=target_cfgs,
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def test_experiment_model_exp_collision_observer() -> None:
|
|
121
|
-
hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
|
|
122
|
-
target_cfgs = [
|
|
123
|
-
TargetConfig(
|
|
124
|
-
target_IDs=[1, 1001], # <- both on same observer
|
|
125
|
-
custom_IDs=list(range(7, 18)),
|
|
126
|
-
energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
|
|
127
|
-
virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
|
|
128
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
129
|
-
firmware2=Firmware(name="msp430_deep_sleep"),
|
|
130
|
-
),
|
|
131
|
-
]
|
|
132
|
-
with pytest.raises(ValueError):
|
|
133
|
-
_ = Experiment(
|
|
134
|
-
id="4567",
|
|
135
|
-
name="meaningful Test-Name",
|
|
136
|
-
time_start=local_now() + timedelta(minutes=30),
|
|
137
|
-
target_configs=target_cfgs,
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def test_experiment_model_exp_missing_target() -> None:
|
|
142
|
-
hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
|
|
143
|
-
with pytest.raises(ValidationError):
|
|
144
|
-
# should raise ValueError in Experiment
|
|
145
|
-
# buts gets already caught in target_config
|
|
146
|
-
_ = [
|
|
147
|
-
TargetConfig(
|
|
148
|
-
target_IDs=[1234567], # <- not existent
|
|
149
|
-
custom_IDs=list(range(7, 18)),
|
|
150
|
-
energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
|
|
151
|
-
virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
|
|
152
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
153
|
-
firmware2=Firmware(name="msp430_deep_sleep"),
|
|
154
|
-
),
|
|
155
|
-
]
|
|
156
|
-
# experiment (like above) removed
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def test_experiment_model_pwrtracing_min() -> None:
|
|
160
|
-
PowerTracing()
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
def test_experiment_model_pwrtracing_fault_post() -> None:
|
|
164
|
-
with pytest.raises(ValueError):
|
|
165
|
-
PowerTracing(calculate_power=True)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
def test_experiment_model_pwrtracing_fault_discard_all() -> None:
|
|
169
|
-
with pytest.raises(ValueError):
|
|
170
|
-
PowerTracing(calculate_power=False, discard_current=True, discard_voltage=True)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
def test_experiment_model_gpiotracing_min() -> None:
|
|
174
|
-
GpioTracing()
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def test_experiment_model_gpiotracing_fault_mask() -> None:
|
|
178
|
-
with pytest.raises(ValueError):
|
|
179
|
-
GpioTracing(mask=0)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
def test_experiment_model_gpioevent_min() -> None:
|
|
183
|
-
gevt = GpioEvent(
|
|
184
|
-
delay=300,
|
|
185
|
-
gpio=GPIO(name="GPIO3"),
|
|
186
|
-
level=GpioLevel.high,
|
|
187
|
-
)
|
|
188
|
-
gevt.get_events()
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
def test_experiment_model_gpioevent_fault_readonly() -> None:
|
|
192
|
-
with pytest.raises(ValueError):
|
|
193
|
-
GpioEvent(
|
|
194
|
-
delay=300,
|
|
195
|
-
gpio=GPIO(name="BAT_OK"),
|
|
196
|
-
level=GpioLevel.high,
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def test_experiment_model_gpioactuation_min() -> None:
|
|
201
|
-
gact = GpioActuation(
|
|
202
|
-
events=[
|
|
203
|
-
GpioEvent(
|
|
204
|
-
delay=300,
|
|
205
|
-
gpio=GPIO(name="GPIO2"),
|
|
206
|
-
level=GpioLevel.high,
|
|
207
|
-
)
|
|
208
|
-
]
|
|
209
|
-
)
|
|
210
|
-
gact.get_gpios()
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
def test_experiment_model_syslogging_min() -> None:
|
|
214
|
-
SystemLogging()
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
def test_experiment_model_tgt_cfg_min1() -> None:
|
|
218
|
-
cfg = TargetConfig(
|
|
219
|
-
target_IDs=[1],
|
|
220
|
-
energy_env=EnergyEnvironment(name="SolarSunny"),
|
|
221
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
222
|
-
)
|
|
223
|
-
for _id in cfg.target_IDs:
|
|
224
|
-
Target(id=_id)
|
|
225
|
-
assert cfg.get_custom_id(1) is None
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
def test_experiment_model_tgt_cfg_min2() -> None:
|
|
229
|
-
cfg = TargetConfig(
|
|
230
|
-
target_IDs=[1, 2],
|
|
231
|
-
custom_IDs=[7, 9],
|
|
232
|
-
energy_env=EnergyEnvironment(name="SolarSunny"),
|
|
233
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
234
|
-
)
|
|
235
|
-
for _id in cfg.target_IDs:
|
|
236
|
-
Target(id=_id)
|
|
237
|
-
assert cfg.get_custom_id(1) == 7
|
|
238
|
-
assert cfg.get_custom_id(2) == 9
|
|
239
|
-
assert cfg.get_custom_id(3) is None
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def test_experiment_model_tgt_cfg_fault_valid_ee() -> None:
|
|
243
|
-
with pytest.raises(ValueError):
|
|
244
|
-
_ = TargetConfig(
|
|
245
|
-
target_IDs=[1],
|
|
246
|
-
energy_env=EnergyEnvironment(name="nuclear"),
|
|
247
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
def test_experiment_model_tgt_cfg_fault_firmware1() -> None:
|
|
252
|
-
with pytest.raises(ValueError):
|
|
253
|
-
_ = TargetConfig(
|
|
254
|
-
target_IDs=[1], # is nRF
|
|
255
|
-
energy_env=EnergyEnvironment(name="SolarSunny"),
|
|
256
|
-
firmware1=Firmware(name="msp430_spi_fram"),
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
def test_experiment_model_tgt_cfg_fault_firmware2() -> None:
|
|
261
|
-
with pytest.raises(ValueError):
|
|
262
|
-
_ = TargetConfig(
|
|
263
|
-
target_IDs=[1], # is nRF
|
|
264
|
-
energy_env=EnergyEnvironment(name="SolarSunny"),
|
|
265
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
266
|
-
firmware2=Firmware(name="nrf52_demo_rf"),
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
def test_experiment_model_tgt_cfg_fault_custom_ids() -> None:
|
|
271
|
-
with pytest.raises(ValueError):
|
|
272
|
-
_ = TargetConfig(
|
|
273
|
-
target_IDs=[1, 2, 3],
|
|
274
|
-
custom_IDs=[0, 1], # not enough
|
|
275
|
-
energy_env=EnergyEnvironment(name="SolarSunny"),
|
|
276
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
277
|
-
)
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
from datetime import timedelta
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
from shepherd_core import local_now
|
|
5
|
-
from shepherd_core.data_models import EnergyEnvironment
|
|
6
|
-
from shepherd_core.data_models import Experiment
|
|
7
|
-
from shepherd_core.data_models import Firmware
|
|
8
|
-
from shepherd_core.data_models import TargetConfig
|
|
9
|
-
from shepherd_core.data_models import VirtualHarvesterConfig
|
|
10
|
-
from shepherd_core.data_models import VirtualSourceConfig
|
|
11
|
-
from shepherd_core.data_models.task import TestbedTasks as TasteBadTasks
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def test_task_generation_file(tmp_path: Path) -> None:
|
|
15
|
-
path = Path(__file__).with_name("example_config_experiment.yaml")
|
|
16
|
-
xp1 = Experiment.from_file(path)
|
|
17
|
-
tb_tasks = TasteBadTasks.from_xp(xp1)
|
|
18
|
-
tb_tasks.to_file(tmp_path / "tbt1.yaml")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def test_task_generation_script(tmp_path: Path) -> None:
|
|
22
|
-
hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
|
|
23
|
-
|
|
24
|
-
target_cfgs = [
|
|
25
|
-
# first init similar to yaml
|
|
26
|
-
TargetConfig(
|
|
27
|
-
target_IDs=list(range(1, 4)),
|
|
28
|
-
custom_IDs=list(range(3)),
|
|
29
|
-
energy_env={"name": "SolarSunny"},
|
|
30
|
-
virtual_source={"name": "diode+capacitor"},
|
|
31
|
-
firmware1={"name": "nrf52_demo_rf"},
|
|
32
|
-
),
|
|
33
|
-
# second Instance fully object-oriented
|
|
34
|
-
TargetConfig(
|
|
35
|
-
target_IDs=list(range(6, 9)),
|
|
36
|
-
custom_IDs=list(range(7, 18)),
|
|
37
|
-
energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
|
|
38
|
-
virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
|
|
39
|
-
firmware1=Firmware(name="nrf52_demo_rf"),
|
|
40
|
-
firmware2=Firmware(name="msp430_deep_sleep"),
|
|
41
|
-
),
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
xperi = Experiment(
|
|
45
|
-
id="4567",
|
|
46
|
-
name="meaningful Test-Name",
|
|
47
|
-
time_start=local_now() + timedelta(minutes=30),
|
|
48
|
-
target_configs=target_cfgs,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
tb_tasks = TasteBadTasks.from_xp(xperi)
|
|
52
|
-
tb_tasks.to_file(tmp_path / "tbt2.yaml")
|