shepherd-core 2023.10.3__tar.gz → 2023.12.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.
Files changed (123) hide show
  1. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/PKG-INFO +16 -5
  2. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/README.md +15 -1
  3. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/setup.cfg +3 -3
  4. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/__init__.py +1 -1
  5. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/base/content.py +3 -8
  6. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/base/shepherd.py +2 -6
  7. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/virtual_source.py +13 -40
  8. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/experiment/experiment.py +3 -8
  9. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/experiment/observer_features.py +4 -9
  10. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/experiment/target_config.py +4 -11
  11. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/task/__init__.py +2 -6
  12. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/task/emulation.py +7 -14
  13. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/task/firmware_mod.py +1 -3
  14. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/task/harvest.py +1 -3
  15. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/cape_fixture.yaml +2 -1
  16. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/observer.py +6 -22
  17. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/observer_fixture.yaml +46 -16
  18. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/target_fixture.yaml +18 -16
  19. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/testbed.py +1 -3
  20. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/testbed_fixture.yaml +2 -0
  21. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/decoder_waveform/uart.py +8 -26
  22. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/fw_tools/__init__.py +1 -3
  23. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/fw_tools/converter.py +4 -12
  24. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/fw_tools/patcher.py +4 -12
  25. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/fw_tools/validation.py +2 -2
  26. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/inventory/__init__.py +3 -9
  27. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/inventory/python.py +7 -5
  28. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/inventory/system.py +2 -5
  29. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/logger.py +1 -3
  30. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/reader.py +45 -41
  31. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/testbed_client/client.py +5 -16
  32. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/testbed_client/fixtures.py +4 -8
  33. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/testbed_client/user_model.py +1 -3
  34. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/vsource/virtual_converter_model.py +4 -14
  35. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/vsource/virtual_harvester_model.py +1 -3
  36. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/vsource/virtual_source_model.py +2 -6
  37. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/writer.py +11 -22
  38. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core.egg-info/PKG-INFO +16 -5
  39. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core.egg-info/requires.txt +0 -3
  40. shepherd_core-2023.12.1/tests/conftest.py +64 -0
  41. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_content_models.py +15 -9
  42. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_experiment_models.py +2 -4
  43. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_task_generation.py +1 -1
  44. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/fw_tools/test_converter.py +11 -0
  45. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/fw_tools/test_patcher.py +11 -4
  46. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/fw_tools/test_validation.py +8 -0
  47. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/inventory/test_inventory.py +1 -3
  48. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/test_cal_hw.py +2 -6
  49. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/test_examples.py +13 -2
  50. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/test_writer.py +2 -2
  51. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/vsource/conftest.py +1 -3
  52. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/vsource/test_converter.py +2 -6
  53. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/vsource/test_harvester.py +3 -9
  54. shepherd_core-2023.10.3/tests/conftest.py +0 -32
  55. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/pyproject.toml +0 -0
  56. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/calibration_hw_def.py +0 -0
  57. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/commons.py +0 -0
  58. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/__init__.py +0 -0
  59. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/base/__init__.py +0 -0
  60. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/base/cal_measurement.py +0 -0
  61. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/base/calibration.py +0 -0
  62. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/base/timezone.py +0 -0
  63. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/base/wrapper.py +0 -0
  64. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/__init__.py +0 -0
  65. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/_external_fixtures.yaml +0 -0
  66. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/energy_environment.py +0 -0
  67. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -0
  68. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/firmware.py +0 -0
  69. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/firmware_datatype.py +0 -0
  70. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/virtual_harvester.py +0 -0
  71. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/virtual_harvester_fixture.yaml +0 -0
  72. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/content/virtual_source_fixture.yaml +0 -0
  73. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/doc_virtual_source.py +0 -0
  74. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/experiment/__init__.py +0 -0
  75. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/task/observer_tasks.py +0 -0
  76. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/task/programming.py +0 -0
  77. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/task/testbed_tasks.py +0 -0
  78. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/__init__.py +0 -0
  79. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/cape.py +0 -0
  80. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/gpio.py +0 -0
  81. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -0
  82. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/mcu.py +0 -0
  83. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/mcu_fixture.yaml +0 -0
  84. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/data_models/testbed/target.py +0 -0
  85. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/decoder_waveform/__init__.py +0 -0
  86. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/fw_tools/converter_elf.py +0 -0
  87. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/inventory/target.py +0 -0
  88. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/testbed_client/__init__.py +0 -0
  89. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core/vsource/__init__.py +0 -0
  90. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core.egg-info/SOURCES.txt +0 -0
  91. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core.egg-info/dependency_links.txt +0 -0
  92. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core.egg-info/top_level.txt +0 -0
  93. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/shepherd_core.egg-info/zip-safe +0 -0
  94. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/__init__.py +0 -0
  95. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/__init__.py +0 -0
  96. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/conftest.py +0 -0
  97. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_cal_data.yaml +0 -0
  98. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_cal_data_faulty.yaml +0 -0
  99. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_cal_meas.yaml +0 -0
  100. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_cal_meas_faulty1.yaml +0 -0
  101. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_cal_meas_faulty2.yaml +0 -0
  102. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_config_emulator.yaml +0 -0
  103. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_config_experiment.yaml +0 -0
  104. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_config_experiment_alternative.yaml +0 -0
  105. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_config_harvester.yaml +0 -0
  106. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_config_testbed.yaml +0 -0
  107. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/example_config_virtsource.yaml +0 -0
  108. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_base_models.py +0 -0
  109. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_content_fixtures.py +0 -0
  110. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_examples.py +0 -0
  111. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_task_models.py +0 -0
  112. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_testbed_fixtures.py +0 -0
  113. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/data_models/test_testbed_models.py +0 -0
  114. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/decoder_waveform/__init__.py +0 -0
  115. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/decoder_waveform/test_decoder.py +0 -0
  116. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/fw_tools/__init__.py +0 -0
  117. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/fw_tools/conftest.py +0 -0
  118. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/inventory/__init__.py +0 -0
  119. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/test_logger.py +0 -0
  120. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/test_reader.py +0 -0
  121. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/testbed_client/__init__.py +0 -0
  122. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/vsource/__init__.py +0 -0
  123. {shepherd_core-2023.10.3 → shepherd_core-2023.12.1}/tests/vsource/test_z.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: shepherd_core
3
- Version: 2023.10.3
3
+ Version: 2023.12.1
4
4
  Summary: Programming- and CLI-Interface for the h5-dataformat of the Shepherd-Testbed
5
5
  Home-page: https://pypi.org/project/shepherd-core/
6
6
  Author: Ingmar Splitt, Kai Geissdoerfer
@@ -46,9 +46,6 @@ Requires-Dist: pwntools-elf-only; extra == "elf"
46
46
  Provides-Extra: inventory
47
47
  Requires-Dist: psutil; extra == "inventory"
48
48
  Provides-Extra: dev
49
- Requires-Dist: black; extra == "dev"
50
- Requires-Dist: pylint; extra == "dev"
51
- Requires-Dist: flake8; extra == "dev"
52
49
  Requires-Dist: twine; extra == "dev"
53
50
  Requires-Dist: pre-commit; extra == "dev"
54
51
  Requires-Dist: pyright; extra == "dev"
@@ -64,7 +61,7 @@ Requires-Dist: coverage; extra == "test"
64
61
  [![PyPiVersion](https://img.shields.io/pypi/v/shepherd_core.svg)](https://pypi.org/project/shepherd_core)
65
62
  [![image](https://img.shields.io/pypi/pyversions/shepherd_core.svg)](https://pypi.python.org/pypi/shepherd-core)
66
63
  [![Pytest](https://github.com/orgua/shepherd-datalib/actions/workflows/py_unittest.yml/badge.svg)](https://github.com/orgua/shepherd-datalib/actions/workflows/py_unittest.yml)
67
- [![CodeStyle](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
64
+ [![CodeStyle](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
68
65
 
69
66
  **Documentation**: <https://orgua.github.io/shepherd/external/shepherd_core.html>
70
67
 
@@ -93,6 +90,20 @@ For postprocessing shepherds .h5-files users want to use [shepherd_data](https:/
93
90
 
94
91
  See [examples](https://github.com/orgua/shepherd-datalib/tree/main/shepherd_core/examples) for more details and usage. Most functionality is showcased there. The [extra](https://github.com/orgua/shepherd-datalib/tree/main/shepherd_core/extra)-directory holds data-generators relevant for the testbed. Notably is a trafficbench-experiment that's used to derive the link-matrix.
95
92
 
93
+ ### Compatibility
94
+
95
+ | OS | PyVersion | Comment |
96
+ |---------|--------------|--------------------------------------------|
97
+ | Ubuntu | 3.8 - 3.12 | |
98
+ | Windows | 3.8 - 3.12 | no support for elf and hex-conversions yet |
99
+ | MacOS | 3.8 - 3.12 | hex-conversion missing |
100
+
101
+ Notes:
102
+ - hex-conversion needs a working and accessible objcopy
103
+ - elf-supports needs
104
+ - ``shepherd-core[elf]`` installs ``pwntools-elf-only``
105
+ - most elf-features also still utilize hex-conversion
106
+
96
107
  ### Data-Models in Detail
97
108
 
98
109
  - new orchestration ``/data-models`` with focus on remote shepherd-testbed
@@ -3,7 +3,7 @@
3
3
  [![PyPiVersion](https://img.shields.io/pypi/v/shepherd_core.svg)](https://pypi.org/project/shepherd_core)
4
4
  [![image](https://img.shields.io/pypi/pyversions/shepherd_core.svg)](https://pypi.python.org/pypi/shepherd-core)
5
5
  [![Pytest](https://github.com/orgua/shepherd-datalib/actions/workflows/py_unittest.yml/badge.svg)](https://github.com/orgua/shepherd-datalib/actions/workflows/py_unittest.yml)
6
- [![CodeStyle](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
6
+ [![CodeStyle](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
7
7
 
8
8
  **Documentation**: <https://orgua.github.io/shepherd/external/shepherd_core.html>
9
9
 
@@ -32,6 +32,20 @@ For postprocessing shepherds .h5-files users want to use [shepherd_data](https:/
32
32
 
33
33
  See [examples](https://github.com/orgua/shepherd-datalib/tree/main/shepherd_core/examples) for more details and usage. Most functionality is showcased there. The [extra](https://github.com/orgua/shepherd-datalib/tree/main/shepherd_core/extra)-directory holds data-generators relevant for the testbed. Notably is a trafficbench-experiment that's used to derive the link-matrix.
34
34
 
35
+ ### Compatibility
36
+
37
+ | OS | PyVersion | Comment |
38
+ |---------|--------------|--------------------------------------------|
39
+ | Ubuntu | 3.8 - 3.12 | |
40
+ | Windows | 3.8 - 3.12 | no support for elf and hex-conversions yet |
41
+ | MacOS | 3.8 - 3.12 | hex-conversion missing |
42
+
43
+ Notes:
44
+ - hex-conversion needs a working and accessible objcopy
45
+ - elf-supports needs
46
+ - ``shepherd-core[elf]`` installs ``pwntools-elf-only``
47
+ - most elf-features also still utilize hex-conversion
48
+
35
49
  ### Data-Models in Detail
36
50
 
37
51
  - new orchestration ``/data-models`` with focus on remote shepherd-testbed
@@ -55,9 +55,6 @@ elf =
55
55
  inventory =
56
56
  psutil
57
57
  dev =
58
- black
59
- pylint
60
- flake8
61
58
  twine
62
59
  pre-commit
63
60
  pyright
@@ -78,6 +75,9 @@ where = .
78
75
  test = pytest
79
76
 
80
77
  [tool:pytest]
78
+ markers =
79
+ converter: automatically added when no objcopy is found (on ubuntu install build-essential)
80
+ elf: automatically added when no elf-support is found (on windows or missing shepherd-core[elf])
81
81
  addopts = -vvv --stepwise
82
82
 
83
83
  [egg_info]
@@ -22,7 +22,7 @@ from .testbed_client.client import TestbedClient
22
22
  from .testbed_client.client import tb_client
23
23
  from .writer import Writer
24
24
 
25
- __version__ = "2023.10.3"
25
+ __version__ = "2023.12.1"
26
26
 
27
27
  __all__ = [
28
28
  "Reader",
@@ -14,9 +14,7 @@ from .timezone import local_now
14
14
  # constr -> to_lower=True, max_length=16, regex=r"^[\w]+$"
15
15
  # ⤷ Regex = AlphaNum
16
16
  IdInt = Annotated[int, Field(ge=0, lt=2**128)]
17
- NameStr = Annotated[
18
- str, StringConstraints(max_length=32, pattern=r'^[^<>:;,?"*|\/\\]+$')
19
- ]
17
+ NameStr = Annotated[str, StringConstraints(max_length=32, pattern=r'^[^<>:;,?"*|\/\\]+$')]
20
18
  # ⤷ Regex = FileSystem-Compatible ASCII
21
19
  SafeStr = Annotated[str, StringConstraints(pattern=r"^[ -~]+$")]
22
20
  # ⤷ Regex = All Printable ASCII-Characters with Space
@@ -35,9 +33,7 @@ class ContentModel(ShpModel):
35
33
  default_factory=id_default,
36
34
  )
37
35
  name: NameStr
38
- description: Annotated[
39
- Optional[SafeStr], Field(description="Required when public")
40
- ] = None
36
+ description: Annotated[Optional[SafeStr], Field(description="Required when public")] = None
41
37
  comment: Optional[SafeStr] = None
42
38
  created: datetime = Field(default_factory=datetime.now)
43
39
 
@@ -57,7 +53,6 @@ class ContentModel(ShpModel):
57
53
  is_visible = self.visible2group or self.visible2all
58
54
  if is_visible and self.description is None:
59
55
  raise ValueError(
60
- "Public instances require a description "
61
- "(check visible2*- and description-field)"
56
+ "Public instances require a description (check visible2*- and description-field)"
62
57
  )
63
58
  return self
@@ -27,9 +27,7 @@ def path2str(
27
27
 
28
28
 
29
29
  def time2int(dumper: Dumper, data: timedelta) -> ScalarNode:
30
- return dumper.represent_scalar(
31
- "tag:yaml.org,2002:int", str(int(data.total_seconds()))
32
- )
30
+ return dumper.represent_scalar("tag:yaml.org,2002:int", str(int(data.total_seconds())))
33
31
 
34
32
 
35
33
  def generic2str(dumper: Dumper, data: Any) -> ScalarNode:
@@ -109,9 +107,7 @@ class ShpModel(BaseModel):
109
107
  def schema_to_file(cls, path: Union[str, Path]) -> None:
110
108
  """Store schema to yaml (for frontend-generators)"""
111
109
  model_dict = cls.model_json_schema()
112
- model_yaml = yaml.safe_dump(
113
- model_dict, default_flow_style=False, sort_keys=False
114
- )
110
+ model_yaml = yaml.safe_dump(model_dict, default_flow_style=False, sort_keys=False)
115
111
  with Path(path).resolve().with_suffix(".yaml").open("w") as f:
116
112
  f.write(model_yaml)
117
113
 
@@ -153,15 +153,9 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
153
153
  dV_output_imed_low_mV = 0
154
154
 
155
155
  # protect from complex solutions (non valid input combinations)
156
- if not (
157
- isinstance(dV_output_en_thrs_mV, (int, float))
158
- and (dV_output_en_thrs_mV >= 0)
159
- ):
156
+ if not (isinstance(dV_output_en_thrs_mV, (int, float)) and (dV_output_en_thrs_mV >= 0)):
160
157
  dV_output_en_thrs_mV = 0
161
- if not (
162
- isinstance(dV_output_imed_low_mV, (int, float))
163
- and (dV_output_imed_low_mV >= 0)
164
- ):
158
+ if not (isinstance(dV_output_imed_low_mV, (int, float)) and (dV_output_imed_low_mV >= 0)):
165
159
  logger.warning("VSrc: C_output shouldn't be larger than C_intermediate")
166
160
  dV_output_imed_low_mV = 0
167
161
 
@@ -171,9 +165,7 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
171
165
 
172
166
  if self.V_intermediate_enable_threshold_mV > V_pre_output_mV:
173
167
  values["dV_enable_output_mV"] = dV_output_en_thrs_mV
174
- values[
175
- "V_enable_output_threshold_mV"
176
- ] = self.V_intermediate_enable_threshold_mV
168
+ values["V_enable_output_threshold_mV"] = self.V_intermediate_enable_threshold_mV
177
169
 
178
170
  else:
179
171
  values["dV_enable_output_mV"] = dV_output_imed_low_mV
@@ -182,20 +174,14 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
182
174
  )
183
175
 
184
176
  if self.V_intermediate_disable_threshold_mV > V_pre_output_mV:
185
- values[
186
- "V_disable_output_threshold_mV"
187
- ] = self.V_intermediate_disable_threshold_mV
177
+ values["V_disable_output_threshold_mV"] = self.V_intermediate_disable_threshold_mV
188
178
  else:
189
179
  values["V_disable_output_threshold_mV"] = V_pre_output_mV
190
180
 
191
181
  else:
192
182
  values["dV_enable_output_mV"] = dV_output_en_thrs_mV
193
- values[
194
- "V_enable_output_threshold_mV"
195
- ] = self.V_intermediate_enable_threshold_mV
196
- values[
197
- "V_disable_output_threshold_mV"
198
- ] = self.V_intermediate_disable_threshold_mV
183
+ values["V_enable_output_threshold_mV"] = self.V_intermediate_enable_threshold_mV
184
+ values["V_disable_output_threshold_mV"] = self.V_intermediate_disable_threshold_mV
199
185
  return values
200
186
 
201
187
  def calc_converter_mode(self, *, log_intermediate_node: bool) -> int:
@@ -286,9 +272,7 @@ class ConverterPRUConfig(ShpModel):
286
272
  states = data.calc_internal_states()
287
273
  return cls(
288
274
  # General
289
- converter_mode=data.calc_converter_mode(
290
- log_intermediate_node=log_intermediate_node
291
- ),
275
+ converter_mode=data.calc_converter_mode(log_intermediate_node=log_intermediate_node),
292
276
  interval_startup_delay_drain_n=round(
293
277
  data.interval_startup_delay_drain_ms * samplerate_sps_default * 1e-3
294
278
  ),
@@ -299,26 +283,16 @@ class ConverterPRUConfig(ShpModel):
299
283
  Constant_us_per_nF_n28=data.calc_cap_constant_us_per_nF_n28(),
300
284
  V_intermediate_init_uV=round(data.V_intermediate_init_mV * 1e3),
301
285
  I_intermediate_leak_nA=round(data.I_intermediate_leak_nA),
302
- V_enable_output_threshold_uV=round(
303
- states["V_enable_output_threshold_mV"] * 1e3
304
- ),
305
- V_disable_output_threshold_uV=round(
306
- states["V_disable_output_threshold_mV"] * 1e3
307
- ),
286
+ V_enable_output_threshold_uV=round(states["V_enable_output_threshold_mV"] * 1e3),
287
+ V_disable_output_threshold_uV=round(states["V_disable_output_threshold_mV"] * 1e3),
308
288
  dV_enable_output_uV=round(states["dV_enable_output_mV"] * 1e3),
309
289
  interval_check_thresholds_n=round(
310
290
  data.interval_check_thresholds_ms * samplerate_sps_default * 1e-3
311
291
  ),
312
- V_pwr_good_enable_threshold_uV=round(
313
- data.V_pwr_good_enable_threshold_mV * 1e3
314
- ),
315
- V_pwr_good_disable_threshold_uV=round(
316
- data.V_pwr_good_disable_threshold_mV * 1e3
317
- ),
292
+ V_pwr_good_enable_threshold_uV=round(data.V_pwr_good_enable_threshold_mV * 1e3),
293
+ V_pwr_good_disable_threshold_uV=round(data.V_pwr_good_disable_threshold_mV * 1e3),
318
294
  immediate_pwr_good_signal=data.immediate_pwr_good_signal,
319
- V_output_log_gpio_threshold_uV=round(
320
- data.V_output_log_gpio_threshold_mV * 1e3
321
- ),
295
+ V_output_log_gpio_threshold_uV=round(data.V_output_log_gpio_threshold_mV * 1e3),
322
296
  # Boost-Converter
323
297
  V_input_boost_threshold_uV=round(data.V_input_boost_threshold_mV * 1e3),
324
298
  V_intermediate_max_uV=round(data.V_intermediate_max_mV * 1e3),
@@ -330,8 +304,7 @@ class ConverterPRUConfig(ShpModel):
330
304
  LUT_input_I_min_log2_nA=data.LUT_input_I_min_log2_nA,
331
305
  LUT_output_I_min_log2_nA=data.LUT_output_I_min_log2_nA,
332
306
  LUT_inp_efficiency_n8=[
333
- [min(255, round(256 * ival)) for ival in il]
334
- for il in data.LUT_input_efficiency
307
+ [min(255, round(256 * ival)) for ival in il] for il in data.LUT_input_efficiency
335
308
  ],
336
309
  LUT_out_inv_efficiency_n4=[
337
310
  min((2**14), round((2**4) / value)) if (value > 0) else int(2**14)
@@ -80,9 +80,7 @@ class Experiment(ShpModel, title="Config of an Experiment"):
80
80
  if len(target_ids) > len(set(target_ids)):
81
81
  raise ValueError("Target-ID used more than once in Experiment!")
82
82
  if len(target_ids) > len(set(custom_ids)):
83
- raise ValueError(
84
- "Custom Target-ID are faulty (some form of id-collisions)!"
85
- )
83
+ raise ValueError("Custom Target-ID are faulty (some form of id-collisions)!")
86
84
 
87
85
  @staticmethod
88
86
  def validate_observers(configs: List[TargetConfig]) -> None:
@@ -92,8 +90,7 @@ class Experiment(ShpModel, title="Config of an Experiment"):
92
90
  obs_ids = [testbed.get_observer(_id).id for _id in target_ids]
93
91
  if len(target_ids) > len(set(obs_ids)):
94
92
  raise ValueError(
95
- "Observer used more than once in Experiment "
96
- "-> only 1 target per observer!"
93
+ "Observer used more than once in Experiment -> only 1 target per observer!"
97
94
  )
98
95
 
99
96
  def get_target_ids(self) -> list:
@@ -104,6 +101,4 @@ class Experiment(ShpModel, title="Config of an Experiment"):
104
101
  if target_id in _config.target_IDs:
105
102
  return _config
106
103
  # gets already caught in target_config - but keep:
107
- raise ValueError(
108
- f"Target-ID {target_id} was not found in Experiment '{self.name}'"
109
- )
104
+ raise ValueError(f"Target-ID {target_id} was not found in Experiment '{self.name}'")
@@ -43,9 +43,7 @@ class PowerTracing(ShpModel, title="Config for Power-Tracing"):
43
43
 
44
44
  discard_all = self.discard_current and self.discard_voltage
45
45
  if not self.calculate_power and discard_all:
46
- raise ValueError(
47
- "Error in config -> tracing enabled, but output gets discarded"
48
- )
46
+ raise ValueError("Error in config -> tracing enabled, but output gets discarded")
49
47
  if self.calculate_power:
50
48
  raise ValueError("postprocessing not implemented ATM")
51
49
  return self
@@ -59,9 +57,7 @@ class GpioTracing(ShpModel, title="Config for GPIO-Tracing"):
59
57
  # initial recording
60
58
  mask: Annotated[int, Field(ge=0, lt=2**10)] = 0b11_1111_1111 # all
61
59
  # ⤷ TODO: custom mask not implemented in PRU, ATM
62
- gpios: Optional[
63
- Annotated[List[GPIO], Field(min_length=1, max_length=10)]
64
- ] = None # = all
60
+ gpios: Optional[Annotated[List[GPIO], Field(min_length=1, max_length=10)]] = None # = all
65
61
  # ⤷ TODO: list of GPIO to build mask, one of both should be internal / computed field
66
62
 
67
63
  # time
@@ -108,9 +104,7 @@ class GpioEvent(ShpModel, title="Config for a GPIO-Event"):
108
104
  @model_validator(mode="after")
109
105
  def post_validation(self) -> Self:
110
106
  if not self.gpio.user_controllable():
111
- raise ValueError(
112
- f"GPIO '{self.gpio.name}' in actuation-event not controllable by user"
113
- )
107
+ raise ValueError(f"GPIO '{self.gpio.name}' in actuation-event not controllable by user")
114
108
  return self
115
109
 
116
110
  def get_events(self) -> np.ndarray:
@@ -138,6 +132,7 @@ class SystemLogging(ShpModel, title="Config for System-Logging"):
138
132
  ptp: bool = True
139
133
  shepherd: bool = True
140
134
  # TODO: rename to kernel, timesync, sheep
135
+ # TODO: add utilization as option
141
136
 
142
137
 
143
138
  # TODO: some more interaction would be good
@@ -22,18 +22,14 @@ class TargetConfig(ShpModel, title="Target Config"):
22
22
  """Configuration for Target Nodes (DuT)"""
23
23
 
24
24
  target_IDs: Annotated[List[IdInt], Field(min_length=1, max_length=128)]
25
- custom_IDs: Optional[
26
- Annotated[List[IdInt16], Field(min_length=1, max_length=128)]
27
- ] = None
25
+ custom_IDs: Optional[Annotated[List[IdInt16], Field(min_length=1, max_length=128)]] = None
28
26
  # ⤷ will replace 'const uint16_t SHEPHERD_NODE_ID' in firmware
29
27
  # if no custom ID is provided, the original ID of target is used
30
28
 
31
29
  energy_env: EnergyEnvironment # alias: input
32
30
  virtual_source: VirtualSourceConfig = VirtualSourceConfig(name="neutral")
33
31
  target_delays: Optional[
34
- Annotated[
35
- List[Annotated[int, Field(ge=0)]], Field(min_length=1, max_length=128)
36
- ]
32
+ Annotated[List[Annotated[int, Field(ge=0)]], Field(min_length=1, max_length=128)]
37
33
  ] = None
38
34
  # ⤷ individual starting times -> allows to use the same environment
39
35
  # TODO: delays not used ATM
@@ -48,9 +44,7 @@ class TargetConfig(ShpModel, title="Target Config"):
48
44
  @model_validator(mode="after")
49
45
  def post_validation(self) -> Self:
50
46
  if not self.energy_env.valid:
51
- raise ValueError(
52
- f"EnergyEnv '{self.energy_env.name}' for target must be valid"
53
- )
47
+ raise ValueError(f"EnergyEnv '{self.energy_env.name}' for target must be valid")
54
48
  for _id in self.target_IDs:
55
49
  target = Target(id=_id)
56
50
  for mcu_num in [1, 2]:
@@ -78,8 +72,7 @@ class TargetConfig(ShpModel, title="Target Config"):
78
72
  t_ids = self.target_IDs
79
73
  if c_ids is not None and (len(set(c_ids)) < len(set(t_ids))):
80
74
  raise ValueError(
81
- f"Provided custom IDs {c_ids} not enough "
82
- f"to cover target range {t_ids}"
75
+ f"Provided custom IDs {c_ids} not enough to cover target range {t_ids}"
83
76
  )
84
77
  # TODO: if custom ids present, firmware must be ELF
85
78
  return self
@@ -32,9 +32,7 @@ __all__ = [
32
32
  ]
33
33
 
34
34
 
35
- def prepare_task(
36
- config: Union[ShpModel, Path, str], observer: Optional[str] = None
37
- ) -> Wrapper:
35
+ def prepare_task(config: Union[ShpModel, Path, str], observer: Optional[str] = None) -> Wrapper:
38
36
  """- Opens file (from Path or str of Path)
39
37
  - wraps task-model
40
38
  - and if it's an TestbedTasks it will extract the correct ObserverTask
@@ -88,9 +86,7 @@ def extract_tasks(shp_wrap: Wrapper, *, no_task_sets: bool = True) -> List[ShpMo
88
86
  content = [ProgrammingTask(**shp_wrap.parameters)]
89
87
  elif shp_wrap.datatype == TestbedTasks.__name__:
90
88
  if no_task_sets:
91
- raise ValueError(
92
- "Model in Wrapper was TestbedTasks -> Task-Sets not allowed!"
93
- )
89
+ raise ValueError("Model in Wrapper was TestbedTasks -> Task-Sets not allowed!")
94
90
  content = [TestbedTasks(**shp_wrap.parameters)]
95
91
  else:
96
92
  raise ValueError("Extractor had unknown task: %s", shp_wrap.datatype)
@@ -29,8 +29,9 @@ class Compression(str, Enum):
29
29
  lzf = "lzf" # not native hdf5
30
30
  gzip1 = 1 # higher compr & load
31
31
  gzip = 1
32
- default = 1
32
+ default = "lzf"
33
33
  null = None
34
+ # NOTE: changed to lzf as BBB needs every straw it can get
34
35
 
35
36
 
36
37
  compressions_allowed: list = [None, "lzf", 1]
@@ -52,8 +53,7 @@ class EmulationTask(ShpModel):
52
53
  force_overwrite: bool = False
53
54
  # ⤷ Overwrite existing file
54
55
  output_compression: Optional[Compression] = Compression.default
55
- # ⤷ should be 1 (level 1 gzip), lzf, or None (order of recommendation)
56
-
56
+ # ⤷ should be lzf, 1 (gzip level 1) or None (order of recommendation)
57
57
  time_start: Optional[datetime] = None
58
58
  # timestamp or unix epoch time, None = ASAP
59
59
  duration: Optional[timedelta] = None
@@ -98,9 +98,7 @@ class EmulationTask(ShpModel):
98
98
  # convert & add local timezone-data
99
99
  has_time = values.get("time_start") is not None
100
100
  if has_time and isinstance(values["time_start"], (int, float)):
101
- values["time_start"] = datetime.fromtimestamp(
102
- values["time_start"], tz=local_tz()
103
- )
101
+ values["time_start"] = datetime.fromtimestamp(values["time_start"], tz=local_tz())
104
102
  if has_time and isinstance(values["time_start"], str):
105
103
  values["time_start"] = datetime.fromisoformat(values["time_start"])
106
104
  if has_time and values["time_start"].tzinfo is None:
@@ -123,18 +121,14 @@ class EmulationTask(ShpModel):
123
121
  "main",
124
122
  "buffer",
125
123
  }:
126
- raise ValueError(
127
- "Voltage Aux must be in float (0 - 4.5) or string 'main' / 'mid'."
128
- )
124
+ raise ValueError("Voltage Aux must be in float (0 - 4.5) or string 'main' / 'mid'.")
129
125
  if self.gpio_actuation is not None:
130
126
  raise ValueError("GPIO Actuation not yet implemented!")
131
127
  return self
132
128
 
133
129
  @classmethod
134
130
  @validate_call
135
- def from_xp(
136
- cls, xp: Experiment, tb: Testbed, tgt_id: IdInt, root_path: Path
137
- ) -> Self:
131
+ def from_xp(cls, xp: Experiment, tb: Testbed, tgt_id: IdInt, root_path: Path) -> Self:
138
132
  obs = tb.get_observer(tgt_id)
139
133
  tgt_cfg = xp.get_target_config(tgt_id)
140
134
 
@@ -144,8 +138,7 @@ class EmulationTask(ShpModel):
144
138
  time_start=copy.copy(xp.time_start),
145
139
  duration=xp.duration,
146
140
  abort_on_error=xp.abort_on_error,
147
- enable_io=(tgt_cfg.gpio_tracing is not None)
148
- or (tgt_cfg.gpio_actuation is not None),
141
+ enable_io=(tgt_cfg.gpio_tracing is not None) or (tgt_cfg.gpio_actuation is not None),
149
142
  io_port=obs.get_target_port(tgt_id),
150
143
  pwr_port=obs.get_target_port(tgt_id),
151
144
  virtual_source=tgt_cfg.virtual_source,
@@ -40,9 +40,7 @@ class FirmwareModTask(ShpModel):
40
40
  FirmwareDType.base64_hex,
41
41
  FirmwareDType.path_hex,
42
42
  }:
43
- logger.warning(
44
- "Firmware is scheduled to get custom-ID but is not in elf-format"
45
- )
43
+ logger.warning("Firmware is scheduled to get custom-ID but is not in elf-format")
46
44
  return self
47
45
 
48
46
  @classmethod
@@ -60,9 +60,7 @@ class HarvestTask(ShpModel):
60
60
  # convert & add local timezone-data, TODO: used twice, refactor
61
61
  has_time = values.get("time_start") is not None
62
62
  if has_time and isinstance(values["time_start"], (int, float)):
63
- values["time_start"] = datetime.fromtimestamp(
64
- values["time_start"], tz=local_tz()
65
- )
63
+ values["time_start"] = datetime.fromtimestamp(values["time_start"], tz=local_tz())
66
64
  if has_time and isinstance(values["time_start"], str):
67
65
  values["time_start"] = datetime.fromisoformat(values["time_start"])
68
66
  if has_time and values["time_start"].tzinfo is None:
@@ -50,6 +50,7 @@
50
50
  inherit_from: cape51
51
51
  id: 1270058
52
52
  name: cape58
53
+ comment: has shields on emu & hrv-circuits -> no effect on RF-Performance
53
54
  - datatype: cape
54
55
  parameters:
55
56
  inherit_from: cape51
@@ -84,7 +85,7 @@
84
85
  inherit_from: cape51
85
86
  id: 1270064
86
87
  name: cape64
87
- comment: only 220u/440uF on 5V
88
+ comment: only 220u/440uF on 5V, had 6x74LVC2T45GT flippend (U11,12,23,24,27,28) - hot air repair
88
89
  - datatype: cape
89
90
  parameters:
90
91
  inherit_from: cape51
@@ -19,9 +19,7 @@ from .target import Target
19
19
 
20
20
  MACStr = Annotated[
21
21
  str,
22
- StringConstraints(
23
- max_length=17, pattern=r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$"
24
- ),
22
+ StringConstraints(max_length=17, pattern=r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$"),
25
23
  ]
26
24
 
27
25
 
@@ -65,23 +63,13 @@ class Observer(ShpModel, title="Shepherd-Sheep"):
65
63
  has_cape = self.cape is not None
66
64
  has_target = (self.target_a is not None) or (self.target_b is not None)
67
65
  if not has_cape and has_target:
68
- raise ValueError(
69
- f"Observer '{self.name}' is faulty " f"-> has targets but no cape"
70
- )
66
+ raise ValueError(f"Observer '{self.name}' is faulty -> has targets but no cape")
71
67
  return self
72
68
 
73
69
  def has_target(self, target_id: int) -> bool:
74
- if (
75
- self.target_a is not None
76
- and target_id == self.target_a.id
77
- and self.target_a.active
78
- ):
70
+ if self.target_a is not None and target_id == self.target_a.id and self.target_a.active:
79
71
  return True
80
- if (
81
- self.target_b is not None
82
- and target_id == self.target_b.id
83
- and self.target_b.active
84
- ):
72
+ if self.target_b is not None and target_id == self.target_b.id and self.target_b.active:
85
73
  return True
86
74
  return False
87
75
 
@@ -91,9 +79,7 @@ class Observer(ShpModel, title="Shepherd-Sheep"):
91
79
  return TargetPort.A
92
80
  if self.target_b is not None and target_id == self.target_b.id:
93
81
  return TargetPort.B
94
- raise ValueError(
95
- f"Target-ID {target_id} was not found in Observer '{self.name}'"
96
- )
82
+ raise ValueError(f"Target-ID {target_id} was not found in Observer '{self.name}'")
97
83
 
98
84
  def get_target(self, target_id: int) -> Target:
99
85
  if self.has_target(target_id):
@@ -101,6 +87,4 @@ class Observer(ShpModel, title="Shepherd-Sheep"):
101
87
  return self.target_a
102
88
  if self.target_b is not None and target_id == self.target_b.id:
103
89
  return self.target_b
104
- raise ValueError(
105
- f"Target-ID {target_id} was not found in Observer '{self.name}'"
106
- )
90
+ raise ValueError(f"Target-ID {target_id} was not found in Observer '{self.name}'")