shepherd-core 2025.6.4__tar.gz → 2025.8.1__tar.gz
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-2025.6.4 → shepherd_core-2025.8.1}/PKG-INFO +3 -6
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/pyproject.toml +1 -5
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/experiment/observer_features.py +8 -2
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/emulation.py +8 -5
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/firmware_mod.py +1 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/harvest.py +3 -3
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/observer_tasks.py +5 -2
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/programming.py +1 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/testbed_tasks.py +6 -1
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/decoder_waveform/uart.py +1 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/fw_tools/patcher.py +60 -34
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/fw_tools/validation.py +7 -1
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/version.py +1 -1
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_source_simulation.py +1 -1
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core.egg-info/PKG-INFO +3 -6
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core.egg-info/requires.txt +3 -5
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/conftest.py +1 -1
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_experiment_models.py +1 -1
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_task_models.py +3 -1
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/fw_tools/test_patcher.py +9 -3
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/README.md +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/eenv_generator.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/experiment_from_yaml.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/experiment_generic_var1.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/experiment_generic_var2.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/experiment_models.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/firmware_model.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/firmware_modification.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/inventory.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/simulate_vharvester.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/simulate_vsource.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/uart_decode_waveform.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/uart_raw2.csv +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/examples/vsource_debug_sim.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/setup.cfg +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/calibration_hw_def.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/commons.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/config.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/cal_measurement.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/calibration.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/content.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/shepherd.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/timezone.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/wrapper.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/_external_fixtures.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/energy_environment.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/firmware.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/firmware_datatype.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/virtual_harvester.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/virtual_harvester_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/virtual_source.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/virtual_source_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/experiment/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/experiment/experiment.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/experiment/target_config.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/readme.md +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/helper_paths.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/cape.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/cape_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/gpio.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/mcu.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/mcu_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/observer.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/observer_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/target.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/target_fixture.old1 +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/target_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/testbed.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/testbed_fixture.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/virtual_source_doc.txt +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/decoder_waveform/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/fw_tools/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/fw_tools/converter.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/fw_tools/converter_elf.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/inventory/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/inventory/python.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/inventory/system.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/inventory/target.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/logger.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/reader.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/cache_path.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/client_abc_fix.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/client_web.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/fixtures.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/user_model.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/target_model.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_converter_model.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_harvester_model.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_harvester_simulation.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_source_model.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/writer.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core.egg-info/SOURCES.txt +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core.egg-info/dependency_links.txt +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core.egg-info/top_level.txt +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core.egg-info/zip-safe +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/conftest.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_cal_data.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_cal_data_faulty.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_cal_meas.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_cal_meas_faulty1.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_cal_meas_faulty2.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_emulator.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_experiment.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_experiment_alternative.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_harvester.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_testbed.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_virtsource.yaml +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_base_models.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_content_fixtures.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_content_models.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_examples.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_task_generation.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_testbed_fixtures.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_testbed_models.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/decoder_waveform/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/decoder_waveform/test_decoder.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/fw_tools/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/fw_tools/build_msp.elf +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/fw_tools/build_nrf.elf +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/fw_tools/conftest.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/fw_tools/test_converter.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/fw_tools/test_validation.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/inventory/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/inventory/test_inventory.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/test_cal_hw.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/test_examples.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/test_logger.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/test_reader.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/test_writer.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/testbed_client/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/vsource/__init__.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/vsource/conftest.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/vsource/test_converter.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/vsource/test_harvester.py +0 -0
- {shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/vsource/test_z.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shepherd_core
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.8.1
|
|
4
4
|
Summary: Programming- and CLI-Interface for the h5-dataformat of the Shepherd-Testbed
|
|
5
5
|
Author-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
|
|
6
6
|
Maintainer-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
|
|
@@ -43,15 +43,12 @@ Requires-Dist: pwntools-elf-only; extra == "elf"
|
|
|
43
43
|
Provides-Extra: inventory
|
|
44
44
|
Requires-Dist: psutil; extra == "inventory"
|
|
45
45
|
Provides-Extra: dev
|
|
46
|
-
Requires-Dist: twine; extra == "dev"
|
|
47
|
-
Requires-Dist: pre-commit; extra == "dev"
|
|
48
|
-
Requires-Dist: pyright; extra == "dev"
|
|
49
|
-
Requires-Dist: ruff; extra == "dev"
|
|
50
|
-
Requires-Dist: mypy; extra == "dev"
|
|
51
46
|
Requires-Dist: types-PyYAML; extra == "dev"
|
|
52
47
|
Provides-Extra: test
|
|
53
48
|
Requires-Dist: pytest; extra == "test"
|
|
54
49
|
Requires-Dist: coverage; extra == "test"
|
|
50
|
+
Provides-Extra: all
|
|
51
|
+
Requires-Dist: shepherd-core[dev,elf,inventory,test]; extra == "all"
|
|
55
52
|
|
|
56
53
|
# Core Library
|
|
57
54
|
|
|
@@ -52,11 +52,6 @@ inventory = [
|
|
|
52
52
|
]
|
|
53
53
|
|
|
54
54
|
dev = [
|
|
55
|
-
"twine",
|
|
56
|
-
"pre-commit",
|
|
57
|
-
"pyright",
|
|
58
|
-
"ruff",
|
|
59
|
-
"mypy",
|
|
60
55
|
"types-PyYAML",
|
|
61
56
|
]
|
|
62
57
|
|
|
@@ -64,6 +59,7 @@ test = [
|
|
|
64
59
|
"pytest",
|
|
65
60
|
"coverage",
|
|
66
61
|
]
|
|
62
|
+
all = ["shepherd-core[elf,inventory,dev,test]"]
|
|
67
63
|
|
|
68
64
|
[project.readme]
|
|
69
65
|
file = "README.md"
|
|
@@ -37,9 +37,15 @@ class PowerTracing(ShpModel, title="Config for Power-Tracing"):
|
|
|
37
37
|
|
|
38
38
|
# further processing of IV-Samples
|
|
39
39
|
only_power: bool = False
|
|
40
|
-
""" ⤷ reduce file-size by calculating power and automatically discard I&V
|
|
40
|
+
""" ⤷ reduce file-size by calculating power and automatically discard I&V
|
|
41
|
+
Caution: increases cpu-utilization on observer - power @ 100 kHz is not recommended
|
|
42
|
+
"""
|
|
41
43
|
samplerate: Annotated[int, Field(ge=10, le=100_000)] = 100_000
|
|
42
44
|
""" ⤷ reduce file-size by re-sampling (mean over x samples)
|
|
45
|
+
|
|
46
|
+
Caution: this option is available for IV-Samples (not only .only_power)
|
|
47
|
+
but results might be faulty for use-cases that are not const-voltage
|
|
48
|
+
Sum(U * I) != Sum(U) * Sum(I)
|
|
43
49
|
Timestamps will be taken from the start of that sample-window.
|
|
44
50
|
example: 10 Hz samplerate will be binning 10k samples via mean() and
|
|
45
51
|
the timestamp for that new sample will be value[0] of the 10k long vector
|
|
@@ -148,7 +154,7 @@ class GpioTracing(ShpModel, title="Config for GPIO-Tracing"):
|
|
|
148
154
|
See doc for nRF_FRAM_Target_v1.3+ to see mapping of target port.
|
|
149
155
|
|
|
150
156
|
Example for skipping UART (pin 0 & 1):
|
|
151
|
-
.
|
|
157
|
+
.gpios = range(2,18)
|
|
152
158
|
|
|
153
159
|
Note:
|
|
154
160
|
- Cape 2.4 (2023) and lower only has 9x GPIO + 1x PwrGood
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/emulation.py
RENAMED
|
@@ -35,8 +35,8 @@ from .helper_paths import path_posix
|
|
|
35
35
|
class Compression(str, Enum):
|
|
36
36
|
"""Options for choosing a dataset-compression."""
|
|
37
37
|
|
|
38
|
-
lzf =
|
|
39
|
-
gzip1 = gzip = 1 # higher compr & load
|
|
38
|
+
lzf = "lzf" # not native hdf5
|
|
39
|
+
gzip1 = gzip = default = 1 # higher compr & load
|
|
40
40
|
null = None
|
|
41
41
|
# NOTE: lzf & external file-compression (xz or zstd) work better than gzip
|
|
42
42
|
# -> even with additional compression
|
|
@@ -127,14 +127,13 @@ class EmulationTask(ShpModel):
|
|
|
127
127
|
|
|
128
128
|
@model_validator(mode="after")
|
|
129
129
|
def post_validation(self) -> Self:
|
|
130
|
-
|
|
131
|
-
time_now = datetime.now().astimezone()
|
|
130
|
+
time_now = datetime.now().astimezone() - timedelta(hours=24)
|
|
132
131
|
if self.time_start is not None and self.time_start < time_now:
|
|
133
132
|
msg = (
|
|
134
133
|
"Start-Time for Emulation can't be in the past "
|
|
135
134
|
f"('{self.time_start}' vs '{time_now}'."
|
|
136
135
|
)
|
|
137
|
-
|
|
136
|
+
log.error(msg) # do not raise anymore - server & clients do not have to match
|
|
138
137
|
if self.duration and self.duration.total_seconds() < 0:
|
|
139
138
|
raise ValueError("Task-Duration can't be negative.")
|
|
140
139
|
if isinstance(self.voltage_aux, str) and self.voltage_aux not in {
|
|
@@ -181,6 +180,10 @@ class EmulationTask(ShpModel):
|
|
|
181
180
|
)
|
|
182
181
|
|
|
183
182
|
def is_contained(self, paths: AbstractSet[PurePosixPath]) -> bool:
|
|
183
|
+
"""Limit paths to allowed directories.
|
|
184
|
+
|
|
185
|
+
TODO: could be added to validator (with a switch)
|
|
186
|
+
"""
|
|
184
187
|
all_ok = any(self.input_path.is_relative_to(path) for path in paths)
|
|
185
188
|
all_ok &= any(self.output_path.is_relative_to(path) for path in paths)
|
|
186
189
|
return all_ok
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/firmware_mod.py
RENAMED
|
@@ -93,6 +93,7 @@ class FirmwareModTask(ShpModel):
|
|
|
93
93
|
return cls(**kwargs)
|
|
94
94
|
|
|
95
95
|
def is_contained(self, paths: AbstractSet[PurePosixPath]) -> bool:
|
|
96
|
+
"""Limit paths to allowed directories."""
|
|
96
97
|
all_ok = any(self.firmware_file.is_relative_to(path) for path in paths)
|
|
97
98
|
if isinstance(self.data, Path):
|
|
98
99
|
all_ok = any(self.data.is_relative_to(path) for path in paths)
|
|
@@ -72,12 +72,11 @@ class HarvestTask(ShpModel):
|
|
|
72
72
|
@model_validator(mode="after")
|
|
73
73
|
def post_validation(self) -> Self:
|
|
74
74
|
# TODO: limit paths
|
|
75
|
-
has_time = self.time_start is not None
|
|
75
|
+
has_time = False # TODO: deactivated, self.time_start is not None
|
|
76
76
|
time_now = datetime.now().astimezone()
|
|
77
77
|
if has_time and self.time_start < time_now:
|
|
78
78
|
msg = (
|
|
79
|
-
"Start-Time for
|
|
80
|
-
f"('{self.time_start}' vs '{time_now}'."
|
|
79
|
+
f"Start-Time for Harvest can't be in the past ('{self.time_start}' vs '{time_now}'."
|
|
81
80
|
)
|
|
82
81
|
raise ValueError(msg)
|
|
83
82
|
if self.duration and self.duration.total_seconds() < 0:
|
|
@@ -85,4 +84,5 @@ class HarvestTask(ShpModel):
|
|
|
85
84
|
return self
|
|
86
85
|
|
|
87
86
|
def is_contained(self, paths: AbstractSet[PurePosixPath]) -> bool:
|
|
87
|
+
"""Limit paths to allowed directories."""
|
|
88
88
|
return any(self.output_path.is_relative_to(path) for path in paths)
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/observer_tasks.py
RENAMED
|
@@ -52,12 +52,14 @@ class ObserverTasks(ShpModel):
|
|
|
52
52
|
|
|
53
53
|
@classmethod
|
|
54
54
|
@validate_call
|
|
55
|
-
def from_xp(cls, xp: Experiment, tb: Testbed, tgt_id: IdInt) -> Self:
|
|
55
|
+
def from_xp(cls, xp: Experiment, xp_folder: str | None, tb: Testbed, tgt_id: IdInt) -> Self:
|
|
56
56
|
if not tb.shared_storage:
|
|
57
57
|
raise ValueError("Implementation currently relies on shared storage!")
|
|
58
58
|
|
|
59
59
|
obs = tb.get_observer(tgt_id)
|
|
60
|
-
|
|
60
|
+
if xp_folder is None:
|
|
61
|
+
xp_folder = xp.folder_name() # moved a layer up for consistent naming
|
|
62
|
+
root_path = tb.data_on_observer / "experiments" / xp_folder
|
|
61
63
|
fw_paths = [root_path / f"fw{_i}_{obs.name}.hex" for _i in [1, 2]]
|
|
62
64
|
|
|
63
65
|
return cls(
|
|
@@ -93,6 +95,7 @@ class ObserverTasks(ShpModel):
|
|
|
93
95
|
return values
|
|
94
96
|
|
|
95
97
|
def is_contained(self, paths: AbstractSet[PurePosixPath]) -> bool:
|
|
98
|
+
"""Limit paths to allowed directories."""
|
|
96
99
|
all_ok = any(self.root_path.is_relative_to(path) for path in paths)
|
|
97
100
|
all_ok &= self.fw1_mod.is_contained(paths)
|
|
98
101
|
all_ok &= self.fw2_mod.is_contained(paths)
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/testbed_tasks.py
RENAMED
|
@@ -34,7 +34,8 @@ class TestbedTasks(ShpModel):
|
|
|
34
34
|
tb = Testbed() # this will query the first (and only) entry of client
|
|
35
35
|
|
|
36
36
|
tgt_ids = xp.get_target_ids()
|
|
37
|
-
|
|
37
|
+
xp_folder = xp.folder_name()
|
|
38
|
+
obs_tasks = [ObserverTasks.from_xp(xp, xp_folder, tb, _id) for _id in tgt_ids]
|
|
38
39
|
return cls(
|
|
39
40
|
name=xp.name,
|
|
40
41
|
observer_tasks=obs_tasks,
|
|
@@ -46,6 +47,9 @@ class TestbedTasks(ShpModel):
|
|
|
46
47
|
return tasks
|
|
47
48
|
return None
|
|
48
49
|
|
|
50
|
+
def get_observers(self) -> set[str]:
|
|
51
|
+
return {tasks.observer for tasks in self.observer_tasks}
|
|
52
|
+
|
|
49
53
|
def get_output_paths(self) -> dict[str, Path]:
|
|
50
54
|
# TODO: computed field preferred, but they don't work here, as
|
|
51
55
|
# - they are always stored in yaml despite "repr=False"
|
|
@@ -56,6 +60,7 @@ class TestbedTasks(ShpModel):
|
|
|
56
60
|
return values
|
|
57
61
|
|
|
58
62
|
def is_contained(self) -> bool:
|
|
63
|
+
"""Limit paths to allowed directories."""
|
|
59
64
|
paths_allowed: AbstractSet[PurePosixPath] = {
|
|
60
65
|
PurePosixPath("/var/shepherd/"),
|
|
61
66
|
PurePosixPath("/tmp/"), # noqa: S108
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"""Read and modify symbols in ELF-files."""
|
|
2
2
|
|
|
3
|
+
import shutil
|
|
3
4
|
from pathlib import Path
|
|
5
|
+
from tempfile import TemporaryDirectory
|
|
4
6
|
from typing import Annotated
|
|
5
7
|
|
|
6
8
|
from pydantic import Field
|
|
@@ -28,22 +30,27 @@ def find_symbol(file_elf: Path, symbol: str) -> bool:
|
|
|
28
30
|
return False
|
|
29
31
|
if ELF is None:
|
|
30
32
|
raise RuntimeError(elf_error_text)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
with TemporaryDirectory(ignore_cleanup_errors=True) as tmp:
|
|
34
|
+
# switcheroo that might prevent windows bug - overwrite fails in modify_symbol_value()
|
|
35
|
+
file_tmp = Path(tmp) / file_elf.name
|
|
36
|
+
shutil.copy(file_elf, file_tmp)
|
|
37
|
+
elf = ELF(path=file_tmp)
|
|
38
|
+
try:
|
|
39
|
+
addr = elf.symbols[symbol]
|
|
40
|
+
except KeyError:
|
|
41
|
+
addr = None
|
|
42
|
+
if addr is None:
|
|
43
|
+
elf.close() # better be safe
|
|
44
|
+
log.debug("Symbol '%s' not found in ELF-File %s", symbol, file_elf.name)
|
|
45
|
+
return False
|
|
46
|
+
log.debug(
|
|
47
|
+
"Symbol '%s' found in ELF-File %s, arch=%s, order=%s",
|
|
48
|
+
symbol,
|
|
49
|
+
file_elf.name,
|
|
50
|
+
elf.arch,
|
|
51
|
+
elf.endian,
|
|
52
|
+
)
|
|
53
|
+
elf.close()
|
|
47
54
|
return True
|
|
48
55
|
|
|
49
56
|
|
|
@@ -60,8 +67,9 @@ def read_symbol(file_elf: Path, symbol: str, length: int) -> int | None:
|
|
|
60
67
|
elf = ELF(path=file_elf)
|
|
61
68
|
addr = elf.symbols[symbol]
|
|
62
69
|
value_raw = elf.read(address=addr, count=length)[-length:]
|
|
70
|
+
endian = elf.endian
|
|
63
71
|
elf.close()
|
|
64
|
-
return int.from_bytes(bytes=value_raw, byteorder=
|
|
72
|
+
return int.from_bytes(bytes=value_raw, byteorder=endian, signed=False)
|
|
65
73
|
|
|
66
74
|
|
|
67
75
|
def read_uid(file_elf: Path) -> int | None:
|
|
@@ -76,8 +84,11 @@ def read_arch(file_elf: Path) -> str | None:
|
|
|
76
84
|
if ELF is None:
|
|
77
85
|
raise RuntimeError(elf_error_text)
|
|
78
86
|
elf = ELF(path=file_elf)
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
elf_type = elf.elftype.lower()
|
|
88
|
+
elf_arch = elf.arch.lower()
|
|
89
|
+
elf.close()
|
|
90
|
+
if "exec" in elf_type:
|
|
91
|
+
return elf_arch
|
|
81
92
|
log.error("ELF is not Executable")
|
|
82
93
|
return None
|
|
83
94
|
|
|
@@ -102,22 +113,37 @@ def modify_symbol_value(
|
|
|
102
113
|
return None
|
|
103
114
|
if ELF is None:
|
|
104
115
|
raise RuntimeError(elf_error_text)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
with TemporaryDirectory(ignore_cleanup_errors=True) as tmp:
|
|
117
|
+
# switcheroo that also prevents windows bug (overwrite fails)
|
|
118
|
+
file_tmp = Path(tmp) / file_elf.name
|
|
119
|
+
shutil.copy(file_elf, file_tmp)
|
|
120
|
+
|
|
121
|
+
elf = ELF(path=file_elf)
|
|
122
|
+
addr = elf.symbols[symbol]
|
|
123
|
+
value_raw = elf.read(address=addr, count=config.UID_SIZE)[-config.UID_SIZE :]
|
|
124
|
+
# ⤷ cutting needed -> msp produces 4b instead of 2
|
|
125
|
+
value_old = int.from_bytes(bytes=value_raw, byteorder=elf.endian, signed=False)
|
|
126
|
+
value_raw = value.to_bytes(length=config.UID_SIZE, byteorder=elf.endian, signed=False)
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
elf.write(address=addr, data=value_raw)
|
|
130
|
+
except AttributeError:
|
|
131
|
+
log.warning("ELF-Modifier failed @%s for symbol '%s'", f"0x{addr:X}", symbol)
|
|
132
|
+
elf.close()
|
|
133
|
+
return None
|
|
134
|
+
|
|
135
|
+
file_new = file_elf if overwrite else file_elf.with_stem(file_elf.stem + "_" + str(value))
|
|
136
|
+
try:
|
|
137
|
+
file_new.unlink(missing_ok=True)
|
|
138
|
+
except PermissionError:
|
|
139
|
+
elf.close()
|
|
140
|
+
log.error(
|
|
141
|
+
"Failed to overwrite file, because it's somehow still in use (typical for WinOS)."
|
|
142
|
+
)
|
|
143
|
+
return None
|
|
144
|
+
elf.save(path=file_new)
|
|
145
|
+
elf.close()
|
|
117
146
|
|
|
118
|
-
file_new = file_elf if overwrite else file_elf.with_stem(file_elf.stem + "_" + str(value))
|
|
119
|
-
elf.save(path=file_new)
|
|
120
|
-
elf.close()
|
|
121
147
|
log.debug(
|
|
122
148
|
"Value of Symbol '%s' modified: %s -> %s @%s",
|
|
123
149
|
symbol,
|
|
@@ -5,6 +5,7 @@ TODO: Work in Progress.
|
|
|
5
5
|
- detection-functions that register in main validator.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
import shutil
|
|
8
9
|
import tempfile
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
|
|
@@ -92,7 +93,12 @@ def is_elf(file: Path) -> bool:
|
|
|
92
93
|
if not file.is_file():
|
|
93
94
|
return False
|
|
94
95
|
try:
|
|
95
|
-
|
|
96
|
+
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmp:
|
|
97
|
+
# switcheroo that might prevent windows bug - overwrite fails in modify_symbol_value()
|
|
98
|
+
file_tmp = Path(tmp) / file.name
|
|
99
|
+
shutil.copy(file, file_tmp)
|
|
100
|
+
elf = ELF(path=file_tmp)
|
|
101
|
+
elf.close()
|
|
96
102
|
except ELFError:
|
|
97
103
|
log.debug("File %s is not ELF - Magic number does not match", file.name)
|
|
98
104
|
return False
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_source_simulation.py
RENAMED
|
@@ -65,7 +65,7 @@ def simulate_source(
|
|
|
65
65
|
stats_internal = np.empty((round(file_inp.runtime_s * file_inp.samplerate_sps), 11))
|
|
66
66
|
try:
|
|
67
67
|
# keep dependencies low
|
|
68
|
-
from matplotlib import pyplot as plt
|
|
68
|
+
from matplotlib import pyplot as plt # noqa: PLC0415
|
|
69
69
|
except ImportError:
|
|
70
70
|
log.warning("Matplotlib not installed, plotting of internals disabled")
|
|
71
71
|
stats_internal = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shepherd_core
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.8.1
|
|
4
4
|
Summary: Programming- and CLI-Interface for the h5-dataformat of the Shepherd-Testbed
|
|
5
5
|
Author-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
|
|
6
6
|
Maintainer-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
|
|
@@ -43,15 +43,12 @@ Requires-Dist: pwntools-elf-only; extra == "elf"
|
|
|
43
43
|
Provides-Extra: inventory
|
|
44
44
|
Requires-Dist: psutil; extra == "inventory"
|
|
45
45
|
Provides-Extra: dev
|
|
46
|
-
Requires-Dist: twine; extra == "dev"
|
|
47
|
-
Requires-Dist: pre-commit; extra == "dev"
|
|
48
|
-
Requires-Dist: pyright; extra == "dev"
|
|
49
|
-
Requires-Dist: ruff; extra == "dev"
|
|
50
|
-
Requires-Dist: mypy; extra == "dev"
|
|
51
46
|
Requires-Dist: types-PyYAML; extra == "dev"
|
|
52
47
|
Provides-Extra: test
|
|
53
48
|
Requires-Dist: pytest; extra == "test"
|
|
54
49
|
Requires-Dist: coverage; extra == "test"
|
|
50
|
+
Provides-Extra: all
|
|
51
|
+
Requires-Dist: shepherd-core[dev,elf,inventory,test]; extra == "all"
|
|
55
52
|
|
|
56
53
|
# Core Library
|
|
57
54
|
|
|
@@ -23,6 +23,7 @@ def test_task_model_emu_min() -> None:
|
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
@pytest.mark.skip(reason="Relaxed in v2025.08.01")
|
|
26
27
|
def test_task_model_emu_fault_in_past() -> None:
|
|
27
28
|
with pytest.raises(ValidationError):
|
|
28
29
|
EmulationTask(
|
|
@@ -91,6 +92,7 @@ def test_task_model_hrv_duration() -> None:
|
|
|
91
92
|
assert hrv.duration.total_seconds() == 42
|
|
92
93
|
|
|
93
94
|
|
|
95
|
+
@pytest.mark.skip(reason="Relaxed in v2025.08.01")
|
|
94
96
|
def test_task_model_hrv_too_late() -> None:
|
|
95
97
|
with pytest.raises(ValidationError):
|
|
96
98
|
HarvestTask(
|
|
@@ -110,7 +112,7 @@ def test_task_model_observer_min1() -> None:
|
|
|
110
112
|
def test_task_model_observer_min2() -> None:
|
|
111
113
|
path = Path(__file__).with_name("example_config_experiment.yaml")
|
|
112
114
|
xp = Experiment.from_file(path)
|
|
113
|
-
ObserverTasks.from_xp(xp=xp, tb=TasteBad(name="shepherd_tud_nes"), tgt_id=1)
|
|
115
|
+
ObserverTasks.from_xp(xp=xp, xp_folder=None, tb=TasteBad(name="shepherd_tud_nes"), tgt_id=1)
|
|
114
116
|
|
|
115
117
|
|
|
116
118
|
def test_task_model_prog_min() -> None:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import shutil
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
|
|
@@ -41,11 +42,13 @@ def test_sym_mod(path_elf: Path, tmp_path: Path) -> None:
|
|
|
41
42
|
def test_sym_mod_overwrite(path_elf: Path, tmp_path: Path) -> None:
|
|
42
43
|
value = 0xCAFE
|
|
43
44
|
sym = "SHEPHERD_NODE_ID"
|
|
45
|
+
assert tmp_path.exists()
|
|
44
46
|
path_new = tmp_path / path_elf.name
|
|
45
47
|
shutil.copy(path_elf, path_new)
|
|
46
|
-
path_gen = fw_tools.modify_symbol_value(
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
path_gen = fw_tools.modify_symbol_value(path_new, sym, value, overwrite=True)
|
|
49
|
+
if path_gen is None and os.name == "nt":
|
|
50
|
+
# TODO: overwriting fails ATM on WinOS (at least in tmp-dir)
|
|
51
|
+
return
|
|
49
52
|
assert path_gen.is_file()
|
|
50
53
|
assert path_gen.as_posix() == path_new.as_posix()
|
|
51
54
|
value_new = fw_tools.read_symbol(path_gen, sym, 2)
|
|
@@ -61,6 +64,9 @@ def test_id_mod(path_elf: Path, tmp_path: Path) -> None:
|
|
|
61
64
|
path_new = tmp_path / path_elf.name
|
|
62
65
|
shutil.copy(path_elf, path_new)
|
|
63
66
|
path_gen = fw_tools.modify_uid(path_new, value)
|
|
67
|
+
if path_gen is None and os.name == "nt":
|
|
68
|
+
# TODO: overwriting fails ATM on WinOS (at least in tmp-dir)
|
|
69
|
+
return
|
|
64
70
|
assert path_gen.as_posix() == path_new.as_posix()
|
|
65
71
|
value_new = fw_tools.read_symbol(path_gen, "SHEPHERD_NODE_ID", 2)
|
|
66
72
|
assert value == value_new
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/__init__.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/cal_measurement.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/calibration.py
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/shepherd.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/base/timezone.py
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/content/firmware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/experiment/__init__.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/experiment/experiment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/__init__.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/task/helper_paths.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/mcu_fixture.yaml
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/observer.py
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/target.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/testbed/testbed.py
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/data_models/virtual_source_doc.txt
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/decoder_waveform/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/cache_path.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/client_abc_fix.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/client_web.py
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/testbed_client/user_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_converter_model.py
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_harvester_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core/vsource/virtual_source_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/shepherd_core.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_cal_data_faulty.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_cal_meas_faulty1.yaml
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_cal_meas_faulty2.yaml
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_emulator.yaml
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_experiment.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_harvester.yaml
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_testbed.yaml
RENAMED
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/example_config_virtsource.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_content_fixtures.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_core-2025.6.4 → shepherd_core-2025.8.1}/tests/data_models/test_testbed_fixtures.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|