shepherd-core 2025.5.3__tar.gz → 2025.6.2__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.5.3 → shepherd_core-2025.6.2}/PKG-INFO +12 -12
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/README.md +9 -9
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/eenv_generator.py +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/uart_decode_waveform.py +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/pyproject.toml +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/__init__.py +2 -2
- shepherd_core-2025.6.2/shepherd_core/commons.py +6 -0
- shepherd_core-2025.6.2/shepherd_core/config.py +34 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/__init__.py +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/calibration.py +13 -8
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/shepherd.py +28 -11
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/wrapper.py +4 -4
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/energy_environment.py +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/firmware.py +13 -8
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/virtual_harvester.py +13 -13
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/virtual_source.py +41 -33
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/virtual_source_fixture.yaml +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/experiment/experiment.py +28 -18
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/experiment/observer_features.py +32 -13
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/experiment/target_config.py +17 -7
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/task/__init__.py +8 -4
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/task/emulation.py +52 -30
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/task/firmware_mod.py +15 -6
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/task/harvest.py +19 -13
- shepherd_core-2025.6.2/shepherd_core/data_models/task/helper_paths.py +15 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/task/observer_tasks.py +20 -18
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/task/programming.py +10 -4
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/task/testbed_tasks.py +16 -7
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/cape_fixture.yaml +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/observer.py +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/observer_fixture.yaml +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/target.py +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/target_fixture.old1 +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/target_fixture.yaml +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/testbed.py +8 -9
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/decoder_waveform/uart.py +7 -7
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/fw_tools/patcher.py +13 -14
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/fw_tools/validation.py +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/inventory/system.py +3 -5
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/logger.py +3 -3
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/reader.py +9 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/testbed_client/cache_path.py +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/testbed_client/client_web.py +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/testbed_client/fixtures.py +5 -5
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/version.py +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/vsource/virtual_harvester_model.py +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/vsource/virtual_source_simulation.py +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/writer.py +2 -2
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core.egg-info/PKG-INFO +12 -12
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core.egg-info/SOURCES.txt +2 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_config_emulator.yaml +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_config_harvester.yaml +1 -1
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_experiment_models.py +1 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/fw_tools/test_patcher.py +6 -6
- shepherd_core-2025.5.3/shepherd_core/commons.py +0 -8
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/experiment_from_yaml.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/experiment_generic_var1.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/experiment_generic_var2.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/experiment_models.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/firmware_model.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/firmware_modification.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/inventory.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/simulate_vharvester.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/simulate_vsource.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/uart_raw2.csv +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/examples/vsource_debug_sim.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/setup.cfg +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/calibration_hw_def.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/cal_measurement.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/content.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/timezone.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/_external_fixtures.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/firmware_datatype.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/virtual_harvester_fixture.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/experiment/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/readme.md +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/cape.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/gpio.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/mcu.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/mcu_fixture.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/testbed/testbed_fixture.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/virtual_source_doc.txt +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/decoder_waveform/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/fw_tools/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/fw_tools/converter.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/fw_tools/converter_elf.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/inventory/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/inventory/python.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/inventory/target.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/testbed_client/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/testbed_client/client_abc_fix.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/testbed_client/user_model.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/vsource/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/vsource/target_model.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/vsource/virtual_converter_model.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/vsource/virtual_harvester_simulation.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/vsource/virtual_source_model.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core.egg-info/dependency_links.txt +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core.egg-info/requires.txt +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core.egg-info/top_level.txt +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core.egg-info/zip-safe +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/conftest.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/conftest.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_cal_data.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_cal_data_faulty.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_cal_meas.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_cal_meas_faulty1.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_cal_meas_faulty2.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_config_experiment.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_config_experiment_alternative.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_config_testbed.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/example_config_virtsource.yaml +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_base_models.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_content_fixtures.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_content_models.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_examples.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_task_generation.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_task_models.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_testbed_fixtures.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/data_models/test_testbed_models.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/decoder_waveform/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/decoder_waveform/test_decoder.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/fw_tools/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/fw_tools/build_msp.elf +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/fw_tools/build_nrf.elf +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/fw_tools/conftest.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/fw_tools/test_converter.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/fw_tools/test_validation.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/inventory/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/inventory/test_inventory.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/test_cal_hw.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/test_examples.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/test_logger.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/test_reader.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/test_writer.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/testbed_client/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/vsource/__init__.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/vsource/conftest.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/vsource/test_converter.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/vsource/test_harvester.py +0 -0
- {shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/tests/vsource/test_z.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shepherd_core
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.6.2
|
|
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>
|
|
7
|
-
Project-URL: Documentation, https://github.com/
|
|
8
|
-
Project-URL: Issues, https://github.com/
|
|
7
|
+
Project-URL: Documentation, https://github.com/nes-lab/shepherd-tools/blob/main/README.md
|
|
8
|
+
Project-URL: Issues, https://github.com/nes-lab/shepherd-tools/issues
|
|
9
9
|
Project-URL: Source, https://pypi.org/project/shepherd-core/
|
|
10
10
|
Keywords: testbed,beaglebone,pru,batteryless,energyharvesting,solar
|
|
11
11
|
Platform: unix
|
|
@@ -56,16 +56,16 @@ Requires-Dist: coverage; extra == "test"
|
|
|
56
56
|
|
|
57
57
|
# Core Library
|
|
58
58
|
|
|
59
|
-
[](https://pypi.org/project/shepherd_core)
|
|
60
60
|
[](https://pypi.python.org/pypi/shepherd-core)
|
|
61
|
-
[](https://github.com/nes-lab/shepherd-tools/actions/workflows/quality_assurance.yaml)
|
|
62
62
|
[](https://github.com/astral-sh/ruff)
|
|
63
63
|
|
|
64
|
-
**Main Documentation**: <https://
|
|
64
|
+
**Main Documentation**: <https://nes-lab.github.io/shepherd>
|
|
65
65
|
|
|
66
|
-
**Source Code**: <https://github.com/
|
|
66
|
+
**Source Code**: <https://github.com/nes-lab/shepherd-tools>
|
|
67
67
|
|
|
68
|
-
**Main Project**: <https://github.com/
|
|
68
|
+
**Main Project**: <https://github.com/nes-lab/shepherd>
|
|
69
69
|
|
|
70
70
|
---
|
|
71
71
|
|
|
@@ -87,7 +87,7 @@ For postprocessing shepherds .h5-files usage of [shepherd_data](https://pypi.org
|
|
|
87
87
|
- decode waveforms (gpio-state & timestamp) to UART
|
|
88
88
|
- create an inventory (for deployed versions of software, hardware)
|
|
89
89
|
|
|
90
|
-
See [official documentation](https://
|
|
90
|
+
See [official documentation](https://nes-lab.github.io/shepherd) or [example scripts](https://github.com/nes-lab/shepherd-tools/tree/main/shepherd_core/examples) for more details and usage. Most functionality is showcased in both. The [extra](https://github.com/nes-lab/shepherd-tools/tree/main/shepherd_core/extra)-directory holds data-generators relevant for the testbed. Notably is a [trafficbench](https://github.com/nes-lab/TrafficBench)-experiment that's used to derive the link-matrix of the testbed-nodes.
|
|
91
91
|
|
|
92
92
|
## Config-Models in Detail
|
|
93
93
|
|
|
@@ -145,9 +145,9 @@ pip install shepherd-data -U
|
|
|
145
145
|
For bleeding-edge-features or dev-work it is possible to install directly from GitHub-Sources (here `dev`-branch):
|
|
146
146
|
|
|
147
147
|
```Shell
|
|
148
|
-
pip install git+https://github.com/
|
|
148
|
+
pip install git+https://github.com/nes-lab/shepherd-tools.git@dev#subdirectory=shepherd_core -U
|
|
149
149
|
# and on sheep with newer debian
|
|
150
|
-
sudo pip install git+https://github.com/
|
|
150
|
+
sudo pip install git+https://github.com/nes-lab/shepherd-tools.git@dev#subdirectory=shepherd_core -U --break-system-packages
|
|
151
151
|
```
|
|
152
152
|
|
|
153
153
|
If you are working with ``.elf``-files (embedding into experiments) you make "objcopy" accessible to python. In Ubuntu, you can either install ``build-essential`` or ``binutils-$ARCH`` with arch being ``msp430`` or ``arm-none-eabi`` for the nRF52.
|
|
@@ -179,7 +179,7 @@ To run the testbench, follow these steps:
|
|
|
179
179
|
3. run the testbench (~ 320 tests):
|
|
180
180
|
|
|
181
181
|
```Shell
|
|
182
|
-
cd shepherd-
|
|
182
|
+
cd shepherd-tools/shepherd_core
|
|
183
183
|
pip3 install ./[tests]
|
|
184
184
|
pytest
|
|
185
185
|
```
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# Core Library
|
|
2
2
|
|
|
3
|
-
[](https://pypi.org/project/shepherd_core)
|
|
4
4
|
[](https://pypi.python.org/pypi/shepherd-core)
|
|
5
|
-
[](https://github.com/nes-lab/shepherd-tools/actions/workflows/quality_assurance.yaml)
|
|
6
6
|
[](https://github.com/astral-sh/ruff)
|
|
7
7
|
|
|
8
|
-
**Main Documentation**: <https://
|
|
8
|
+
**Main Documentation**: <https://nes-lab.github.io/shepherd>
|
|
9
9
|
|
|
10
|
-
**Source Code**: <https://github.com/
|
|
10
|
+
**Source Code**: <https://github.com/nes-lab/shepherd-tools>
|
|
11
11
|
|
|
12
|
-
**Main Project**: <https://github.com/
|
|
12
|
+
**Main Project**: <https://github.com/nes-lab/shepherd>
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
@@ -31,7 +31,7 @@ For postprocessing shepherds .h5-files usage of [shepherd_data](https://pypi.org
|
|
|
31
31
|
- decode waveforms (gpio-state & timestamp) to UART
|
|
32
32
|
- create an inventory (for deployed versions of software, hardware)
|
|
33
33
|
|
|
34
|
-
See [official documentation](https://
|
|
34
|
+
See [official documentation](https://nes-lab.github.io/shepherd) or [example scripts](https://github.com/nes-lab/shepherd-tools/tree/main/shepherd_core/examples) for more details and usage. Most functionality is showcased in both. The [extra](https://github.com/nes-lab/shepherd-tools/tree/main/shepherd_core/extra)-directory holds data-generators relevant for the testbed. Notably is a [trafficbench](https://github.com/nes-lab/TrafficBench)-experiment that's used to derive the link-matrix of the testbed-nodes.
|
|
35
35
|
|
|
36
36
|
## Config-Models in Detail
|
|
37
37
|
|
|
@@ -89,9 +89,9 @@ pip install shepherd-data -U
|
|
|
89
89
|
For bleeding-edge-features or dev-work it is possible to install directly from GitHub-Sources (here `dev`-branch):
|
|
90
90
|
|
|
91
91
|
```Shell
|
|
92
|
-
pip install git+https://github.com/
|
|
92
|
+
pip install git+https://github.com/nes-lab/shepherd-tools.git@dev#subdirectory=shepherd_core -U
|
|
93
93
|
# and on sheep with newer debian
|
|
94
|
-
sudo pip install git+https://github.com/
|
|
94
|
+
sudo pip install git+https://github.com/nes-lab/shepherd-tools.git@dev#subdirectory=shepherd_core -U --break-system-packages
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
If you are working with ``.elf``-files (embedding into experiments) you make "objcopy" accessible to python. In Ubuntu, you can either install ``build-essential`` or ``binutils-$ARCH`` with arch being ``msp430`` or ``arm-none-eabi`` for the nRF52.
|
|
@@ -123,7 +123,7 @@ To run the testbench, follow these steps:
|
|
|
123
123
|
3. run the testbench (~ 320 tests):
|
|
124
124
|
|
|
125
125
|
```Shell
|
|
126
|
-
cd shepherd-
|
|
126
|
+
cd shepherd-tools/shepherd_core
|
|
127
127
|
pip3 install ./[tests]
|
|
128
128
|
pytest
|
|
129
129
|
```
|
|
@@ -8,7 +8,7 @@ from tqdm import trange
|
|
|
8
8
|
|
|
9
9
|
from shepherd_core import Reader as ShpReader
|
|
10
10
|
from shepherd_core import Writer as ShpWriter
|
|
11
|
-
from shepherd_core import
|
|
11
|
+
from shepherd_core.logger import log
|
|
12
12
|
|
|
13
13
|
# Config
|
|
14
14
|
voltages_V = [4.0, 2.0]
|
|
@@ -26,7 +26,7 @@ for _v, _c in product(voltages_V, currents_A):
|
|
|
26
26
|
file_path = path_here / f"{name}.h5"
|
|
27
27
|
|
|
28
28
|
if file_path.exists():
|
|
29
|
-
|
|
29
|
+
log.info("File exists, will skip: %s", file_path.name)
|
|
30
30
|
else:
|
|
31
31
|
with ShpWriter(file_path) as file:
|
|
32
32
|
file.store_hostname("artificial")
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from timeit import timeit
|
|
5
5
|
|
|
6
|
-
from shepherd_core import logger
|
|
7
6
|
from shepherd_core.decoder_waveform import Uart
|
|
7
|
+
from shepherd_core.logger import log
|
|
8
8
|
|
|
9
9
|
# file captured with logic analyzer, 15.5k events (2700 symbols, 61 lines)
|
|
10
10
|
trace = Path(__file__).parent / "uart_raw2.csv"
|
|
@@ -13,7 +13,7 @@ uwd = Uart(trace)
|
|
|
13
13
|
sym = uwd.get_symbols()
|
|
14
14
|
lne = uwd.get_lines()
|
|
15
15
|
txt = uwd.get_text()
|
|
16
|
-
|
|
16
|
+
log.info(txt)
|
|
17
17
|
|
|
18
18
|
do_analysis = False
|
|
19
19
|
if do_analysis:
|
|
@@ -71,8 +71,8 @@ file = "README.md"
|
|
|
71
71
|
content-type = "text/markdown"
|
|
72
72
|
|
|
73
73
|
[project.urls]
|
|
74
|
-
Documentation = "https://github.com/
|
|
75
|
-
Issues = "https://github.com/
|
|
74
|
+
Documentation = "https://github.com/nes-lab/shepherd-tools/blob/main/README.md"
|
|
75
|
+
Issues = "https://github.com/nes-lab/shepherd-tools/issues"
|
|
76
76
|
Source = "https://pypi.org/project/shepherd-core/"
|
|
77
77
|
|
|
78
78
|
[build-system]
|
|
@@ -17,7 +17,7 @@ from .data_models.task.emulation import Compression
|
|
|
17
17
|
from .inventory import Inventory
|
|
18
18
|
from .logger import get_verbose_level
|
|
19
19
|
from .logger import increase_verbose_level
|
|
20
|
-
from .logger import
|
|
20
|
+
from .logger import log
|
|
21
21
|
from .reader import Reader
|
|
22
22
|
from .testbed_client.client_web import WebClient
|
|
23
23
|
from .version import version
|
|
@@ -41,5 +41,5 @@ __all__ = [
|
|
|
41
41
|
"increase_verbose_level",
|
|
42
42
|
"local_now",
|
|
43
43
|
"local_tz",
|
|
44
|
-
"
|
|
44
|
+
"log",
|
|
45
45
|
]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Container for a common configuration.
|
|
2
|
+
|
|
3
|
+
This can be adapted by the user by importing 'config' and changing its variables.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
from pydantic import HttpUrl
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ConfigDefault(BaseModel):
|
|
11
|
+
"""Container for a common configuration."""
|
|
12
|
+
|
|
13
|
+
__slots__ = ()
|
|
14
|
+
|
|
15
|
+
TESTBED: str = "shepherd_tud_nes"
|
|
16
|
+
"""name of the testbed to validate against - if enabled - see switch below"""
|
|
17
|
+
VALIDATE_INFRA: bool = True
|
|
18
|
+
"""switch to turn on / off deep validation of data models also considering the current
|
|
19
|
+
layout & infrastructure of the testbed.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
SAMPLERATE_SPS: int = 100_000
|
|
23
|
+
"""Rate of IV-Recording of the testbed."""
|
|
24
|
+
|
|
25
|
+
UID_NAME: str = "SHEPHERD_NODE_ID"
|
|
26
|
+
"""Variable name to patch in ELF-file"""
|
|
27
|
+
UID_SIZE: int = 2
|
|
28
|
+
"""Variable size in Byte"""
|
|
29
|
+
|
|
30
|
+
TESTBED_SERVER: HttpUrl = "https://shepherd.cfaed.tu-dresden.de:8000/"
|
|
31
|
+
"""Server that holds up to date testbed fixtures"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
config = ConfigDefault()
|
{shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/calibration.py
RENAMED
|
@@ -95,14 +95,19 @@ cal_hrv_legacy = { # legacy translator
|
|
|
95
95
|
"adc_voltage": "adc_V_Sense", # datalog voltage
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
# defaults (pre-init complex types)
|
|
99
|
+
cal_pair_dac_V = CalibrationPair.from_fn(dac_voltage_to_raw, unit="V")
|
|
100
|
+
cal_pair_adc_V = CalibrationPair.from_fn(adc_voltage_to_raw, unit="V")
|
|
101
|
+
cal_pair_adc_C = CalibrationPair.from_fn(adc_current_to_raw, unit="A")
|
|
102
|
+
|
|
98
103
|
|
|
99
104
|
class CalibrationHarvester(ShpModel):
|
|
100
105
|
"""Container for all calibration-pairs for that device."""
|
|
101
106
|
|
|
102
|
-
dac_V_Hrv: CalibrationPair =
|
|
103
|
-
dac_V_Sim: CalibrationPair =
|
|
104
|
-
adc_V_Sense: CalibrationPair =
|
|
105
|
-
adc_C_Hrv: CalibrationPair =
|
|
107
|
+
dac_V_Hrv: CalibrationPair = cal_pair_dac_V
|
|
108
|
+
dac_V_Sim: CalibrationPair = cal_pair_dac_V
|
|
109
|
+
adc_V_Sense: CalibrationPair = cal_pair_adc_V
|
|
110
|
+
adc_C_Hrv: CalibrationPair = cal_pair_adc_C
|
|
106
111
|
|
|
107
112
|
def export_for_sysfs(self) -> dict:
|
|
108
113
|
"""Convert and write the essential data.
|
|
@@ -143,10 +148,10 @@ class CalibrationEmulator(ShpModel):
|
|
|
143
148
|
Differentiates between both target-ports A/B.
|
|
144
149
|
"""
|
|
145
150
|
|
|
146
|
-
dac_V_A: CalibrationPair =
|
|
147
|
-
dac_V_B: CalibrationPair =
|
|
148
|
-
adc_C_A: CalibrationPair =
|
|
149
|
-
adc_C_B: CalibrationPair =
|
|
151
|
+
dac_V_A: CalibrationPair = cal_pair_dac_V
|
|
152
|
+
dac_V_B: CalibrationPair = cal_pair_dac_V
|
|
153
|
+
adc_C_A: CalibrationPair = cal_pair_adc_C
|
|
154
|
+
adc_C_B: CalibrationPair = cal_pair_adc_C
|
|
150
155
|
|
|
151
156
|
def export_for_sysfs(self) -> dict:
|
|
152
157
|
"""Convert and write the essential data.
|
{shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/base/shepherd.py
RENAMED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import hashlib
|
|
4
4
|
import pathlib
|
|
5
|
+
import pickle
|
|
5
6
|
from collections.abc import Generator
|
|
6
7
|
from datetime import timedelta
|
|
7
8
|
from ipaddress import IPv4Address
|
|
@@ -126,10 +127,12 @@ class ShpModel(BaseModel):
|
|
|
126
127
|
comment: Optional[str] = None,
|
|
127
128
|
*,
|
|
128
129
|
minimal: bool = True,
|
|
130
|
+
use_pickle: bool = False,
|
|
129
131
|
) -> Path:
|
|
130
132
|
"""Store data to yaml in a wrapper.
|
|
131
133
|
|
|
132
134
|
minimal: stores minimal set (filters out unset & default parameters)
|
|
135
|
+
pickle: uses pickle to serialize data, on BBB >100x faster for large files
|
|
133
136
|
comment: documentation.
|
|
134
137
|
"""
|
|
135
138
|
model_dict = self.model_dump(exclude_unset=minimal)
|
|
@@ -139,25 +142,39 @@ class ShpModel(BaseModel):
|
|
|
139
142
|
created=local_now(),
|
|
140
143
|
parameters=model_dict,
|
|
141
144
|
)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
if use_pickle:
|
|
146
|
+
model_serial = pickle.dumps(model_dict, fix_imports=True)
|
|
147
|
+
model_path = Path(path).resolve().with_suffix(".pickle")
|
|
148
|
+
else:
|
|
149
|
+
# TODO: x64 windows supports CSafeLoader/dumper,
|
|
150
|
+
# there are examples that replace load if avail
|
|
151
|
+
model_serial = yaml.safe_dump(
|
|
152
|
+
model_wrap.model_dump(exclude_unset=minimal, exclude_defaults=minimal),
|
|
153
|
+
default_flow_style=False,
|
|
154
|
+
sort_keys=False,
|
|
155
|
+
)
|
|
156
|
+
model_path = Path(path).resolve().with_suffix(".yaml")
|
|
147
157
|
# TODO: handle directory
|
|
148
|
-
|
|
158
|
+
|
|
149
159
|
if not model_path.parent.exists():
|
|
150
160
|
model_path.parent.mkdir(parents=True)
|
|
151
161
|
with model_path.open("w") as f:
|
|
152
|
-
f.write(
|
|
162
|
+
f.write(model_serial)
|
|
153
163
|
return model_path
|
|
154
164
|
|
|
155
165
|
@classmethod
|
|
156
166
|
def from_file(cls, path: Union[str, Path]) -> Self:
|
|
157
|
-
"""Load from
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
167
|
+
"""Load from YAML or pickle file."""
|
|
168
|
+
path: Path = Path(path)
|
|
169
|
+
if not Path(path).exists():
|
|
170
|
+
raise FileNotFoundError
|
|
171
|
+
if path.suffix.lower() == ".pickle":
|
|
172
|
+
with Path(path).open("rb") as shp_file:
|
|
173
|
+
shp_wrap = pickle.load(shp_file, fix_imports=True) # noqa: S301
|
|
174
|
+
else:
|
|
175
|
+
with Path(path).open() as shp_file:
|
|
176
|
+
shp_dict = yaml.safe_load(shp_file)
|
|
177
|
+
shp_wrap = Wrapper(**shp_dict)
|
|
161
178
|
if shp_wrap.datatype != cls.__name__:
|
|
162
179
|
raise ValueError("Model in file does not match the requirement")
|
|
163
180
|
return cls(**shp_wrap.parameters)
|
|
@@ -17,11 +17,11 @@ class Wrapper(BaseModel):
|
|
|
17
17
|
"""Generalized web- & file-interface for all models with dynamic typecasting."""
|
|
18
18
|
|
|
19
19
|
datatype: str
|
|
20
|
-
|
|
20
|
+
""" ⤷ model-name"""
|
|
21
21
|
comment: Optional[SafeStrClone] = None
|
|
22
22
|
created: Optional[datetime] = None
|
|
23
|
-
|
|
23
|
+
""" ⤷ Optional metadata"""
|
|
24
24
|
lib_ver: Optional[str] = version
|
|
25
|
-
|
|
25
|
+
""" ⤷ for debug-purposes and later compatibility-checks"""
|
|
26
26
|
parameters: dict
|
|
27
|
-
|
|
27
|
+
""" ⤷ ShpModel"""
|
|
@@ -28,7 +28,7 @@ class EnergyEnvironment(ContentModel):
|
|
|
28
28
|
data_path: Path
|
|
29
29
|
data_type: EnergyDType
|
|
30
30
|
data_local: bool = True
|
|
31
|
-
|
|
31
|
+
""" ⤷ signals that file has to be copied to testbed"""
|
|
32
32
|
|
|
33
33
|
duration: PositiveFloat
|
|
34
34
|
energy_Ws: PositiveFloat
|
{shepherd_core-2025.5.3 → shepherd_core-2025.6.2}/shepherd_core/data_models/content/firmware.py
RENAMED
|
@@ -19,7 +19,7 @@ from typing_extensions import Unpack
|
|
|
19
19
|
from shepherd_core import fw_tools
|
|
20
20
|
from shepherd_core.data_models.base.content import ContentModel
|
|
21
21
|
from shepherd_core.data_models.testbed.mcu import MCU
|
|
22
|
-
from shepherd_core.logger import
|
|
22
|
+
from shepherd_core.logger import log
|
|
23
23
|
from shepherd_core.testbed_client import tb_client
|
|
24
24
|
|
|
25
25
|
from .firmware_datatype import FirmwareDType
|
|
@@ -62,7 +62,7 @@ class Firmware(ContentModel, title="Firmware of Target"):
|
|
|
62
62
|
data_type: FirmwareDType
|
|
63
63
|
data_hash: Optional[str] = None
|
|
64
64
|
data_local: bool = True
|
|
65
|
-
|
|
65
|
+
""" ⤷ signals that file has to be copied to testbed"""
|
|
66
66
|
|
|
67
67
|
@model_validator(mode="before")
|
|
68
68
|
@classmethod
|
|
@@ -125,13 +125,18 @@ class Firmware(ContentModel, title="Firmware of Target"):
|
|
|
125
125
|
if "mcu" not in kwargs:
|
|
126
126
|
kwargs["mcu"] = arch_to_mcu[arch]
|
|
127
127
|
|
|
128
|
+
# verification of ELF - warn if something is off
|
|
129
|
+
# -> adds ARCH if it is able to derive
|
|
128
130
|
if kwargs["data_type"] == FirmwareDType.base64_elf:
|
|
129
131
|
arch = fw_tools.read_arch(file)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
try:
|
|
133
|
+
if "msp430" in arch and not fw_tools.is_elf_msp430(file):
|
|
134
|
+
raise ValueError("File is not a ELF for msp430")
|
|
135
|
+
if ("nrf52" in arch or "arm" in arch) and not fw_tools.is_elf_nrf52(file):
|
|
136
|
+
raise ValueError("File is not a ELF for nRF52")
|
|
137
|
+
except RuntimeError:
|
|
138
|
+
log.warning("ObjCopy not found -> Arch of Firmware can't be verified")
|
|
139
|
+
log.debug("ELF-File '%s' has arch: %s", file.name, arch)
|
|
135
140
|
if "mcu" not in kwargs:
|
|
136
141
|
kwargs["mcu"] = arch_to_mcu[arch]
|
|
137
142
|
|
|
@@ -154,7 +159,7 @@ class Firmware(ContentModel, title="Firmware of Target"):
|
|
|
154
159
|
match = self.data_hash == hash_new
|
|
155
160
|
|
|
156
161
|
if not match:
|
|
157
|
-
|
|
162
|
+
log.warning("FW-Hash does not match with stored value!")
|
|
158
163
|
# TODO: it might be more appropriate to raise here
|
|
159
164
|
return match
|
|
160
165
|
|
|
@@ -10,11 +10,11 @@ from pydantic import Field
|
|
|
10
10
|
from pydantic import model_validator
|
|
11
11
|
from typing_extensions import Self
|
|
12
12
|
|
|
13
|
-
from shepherd_core.
|
|
13
|
+
from shepherd_core.config import config
|
|
14
14
|
from shepherd_core.data_models.base.calibration import CalibrationHarvester
|
|
15
15
|
from shepherd_core.data_models.base.content import ContentModel
|
|
16
16
|
from shepherd_core.data_models.base.shepherd import ShpModel
|
|
17
|
-
from shepherd_core.logger import
|
|
17
|
+
from shepherd_core.logger import log
|
|
18
18
|
from shepherd_core.testbed_client import tb_client
|
|
19
19
|
|
|
20
20
|
from .energy_environment import EnergyDType
|
|
@@ -310,7 +310,7 @@ class VirtualHarvesterConfig(ContentModel, title="Config for the Harvester"):
|
|
|
310
310
|
if values["name"] == "neutral":
|
|
311
311
|
# TODO: same test is later done in calc_algorithm_num() again
|
|
312
312
|
raise ValueError("Resulting Harvester can't be neutral")
|
|
313
|
-
|
|
313
|
+
log.debug("VHrv-Inheritances: %s", chain)
|
|
314
314
|
|
|
315
315
|
# post corrections -> should be in separate validator
|
|
316
316
|
cal = CalibrationHarvester() # TODO: as argument?
|
|
@@ -363,16 +363,16 @@ class VirtualHarvesterConfig(ContentModel, title="Config for the Harvester"):
|
|
|
363
363
|
def calc_timings_ms(self, *, for_emu: bool) -> tuple[float, float]:
|
|
364
364
|
"""factor-in model-internal timing-constraints."""
|
|
365
365
|
window_length = self.samples_n * (1 + self.wait_cycles)
|
|
366
|
-
time_min_ms = (1 + self.wait_cycles) * 1_000 /
|
|
366
|
+
time_min_ms = (1 + self.wait_cycles) * 1_000 / config.SAMPLERATE_SPS
|
|
367
367
|
if for_emu:
|
|
368
|
-
window_ms = window_length * 1_000 /
|
|
368
|
+
window_ms = window_length * 1_000 / config.SAMPLERATE_SPS
|
|
369
369
|
time_min_ms = max(time_min_ms, window_ms)
|
|
370
370
|
|
|
371
371
|
interval_ms = min(max(self.interval_ms, time_min_ms), 1_000_000)
|
|
372
372
|
duration_ms = min(max(self.duration_ms, time_min_ms), interval_ms)
|
|
373
373
|
_ratio = (duration_ms / interval_ms) / (self.duration_ms / self.interval_ms)
|
|
374
374
|
if (_ratio - 1) > 0.1:
|
|
375
|
-
|
|
375
|
+
log.debug(
|
|
376
376
|
"Ratio between interval & duration has changed "
|
|
377
377
|
"more than 10%% due to constraints (%.4f)",
|
|
378
378
|
_ratio,
|
|
@@ -453,16 +453,16 @@ class HarvesterPRUConfig(ShpModel):
|
|
|
453
453
|
voltage_min_uV: u32
|
|
454
454
|
voltage_max_uV: u32
|
|
455
455
|
voltage_step_uV: u32
|
|
456
|
-
|
|
456
|
+
""" ⤷ for window-based algo like ivcurve"""
|
|
457
457
|
current_limit_nA: u32
|
|
458
|
-
|
|
458
|
+
""" ⤷ lower bound to detect zero current"""
|
|
459
459
|
setpoint_n8: u32
|
|
460
460
|
interval_n: u32
|
|
461
|
-
|
|
461
|
+
""" ⤷ between measurements"""
|
|
462
462
|
duration_n: u32
|
|
463
|
-
|
|
463
|
+
""" ⤷ of measurement"""
|
|
464
464
|
wait_cycles_n: u32
|
|
465
|
-
|
|
465
|
+
""" ⤷ for DAC to settle"""
|
|
466
466
|
|
|
467
467
|
@classmethod
|
|
468
468
|
def from_vhrv(
|
|
@@ -517,7 +517,7 @@ class HarvesterPRUConfig(ShpModel):
|
|
|
517
517
|
voltage_step_uV=round(voltage_step_mV * 10**3),
|
|
518
518
|
current_limit_nA=round(data.current_limit_uA * 10**3),
|
|
519
519
|
setpoint_n8=round(min(255, data.setpoint_n * 2**8)),
|
|
520
|
-
interval_n=round(interval_ms *
|
|
521
|
-
duration_n=round(duration_ms *
|
|
520
|
+
interval_n=round(interval_ms * config.SAMPLERATE_SPS * 1e-3),
|
|
521
|
+
duration_n=round(duration_ms * config.SAMPLERATE_SPS * 1e-3),
|
|
522
522
|
wait_cycles_n=data.wait_cycles,
|
|
523
523
|
)
|