shepherd-core 2025.4.1__tar.gz → 2025.5.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.
Files changed (147) hide show
  1. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/PKG-INFO +2 -3
  2. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/experiment_generic_var1.py +8 -15
  3. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/experiment_generic_var2.py +6 -13
  4. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/experiment_models.py +12 -17
  5. shepherd_core-2025.5.2/examples/inventory.py +20 -0
  6. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/simulate_vharvester.py +4 -8
  7. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/simulate_vsource.py +1 -5
  8. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/pyproject.toml +6 -3
  9. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/calibration_hw_def.py +11 -11
  10. shepherd_core-2025.5.2/shepherd_core/commons.py +8 -0
  11. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/__init__.py +2 -0
  12. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/base/cal_measurement.py +10 -11
  13. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/base/calibration.py +7 -6
  14. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/base/content.py +1 -1
  15. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/base/shepherd.py +6 -7
  16. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/base/wrapper.py +2 -2
  17. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/_external_fixtures.yaml +32 -32
  18. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/energy_environment.py +6 -5
  19. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/firmware.py +9 -7
  20. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/virtual_harvester.py +34 -26
  21. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/virtual_harvester_fixture.yaml +2 -2
  22. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/virtual_source.py +20 -17
  23. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/virtual_source_fixture.yaml +3 -3
  24. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/experiment/experiment.py +15 -15
  25. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/experiment/observer_features.py +109 -16
  26. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/experiment/target_config.py +17 -12
  27. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/task/__init__.py +11 -8
  28. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/task/emulation.py +32 -17
  29. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/task/firmware_mod.py +11 -11
  30. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/task/harvest.py +7 -6
  31. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/task/observer_tasks.py +7 -7
  32. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/task/programming.py +13 -12
  33. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/task/testbed_tasks.py +8 -8
  34. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/cape.py +7 -6
  35. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/gpio.py +8 -7
  36. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/mcu.py +8 -7
  37. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/mcu_fixture.yaml +4 -4
  38. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/observer.py +9 -7
  39. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/target.py +9 -7
  40. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/testbed.py +11 -10
  41. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/virtual_source_doc.txt +3 -3
  42. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/decoder_waveform/uart.py +5 -5
  43. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/fw_tools/converter.py +10 -6
  44. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/fw_tools/patcher.py +14 -15
  45. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/fw_tools/validation.py +11 -6
  46. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/inventory/__init__.py +6 -6
  47. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/inventory/python.py +1 -1
  48. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/inventory/system.py +11 -8
  49. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/inventory/target.py +3 -3
  50. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/logger.py +2 -2
  51. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/reader.py +105 -78
  52. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/testbed_client/client_abc_fix.py +22 -16
  53. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/testbed_client/client_web.py +18 -11
  54. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/testbed_client/fixtures.py +21 -22
  55. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/testbed_client/user_model.py +6 -5
  56. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/version.py +1 -1
  57. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/vsource/target_model.py +3 -3
  58. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/vsource/virtual_converter_model.py +3 -3
  59. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/vsource/virtual_harvester_model.py +7 -9
  60. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/vsource/virtual_harvester_simulation.py +7 -6
  61. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/vsource/virtual_source_model.py +6 -5
  62. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/vsource/virtual_source_simulation.py +8 -7
  63. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/writer.py +37 -39
  64. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core.egg-info/PKG-INFO +2 -3
  65. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/conftest.py +1 -1
  66. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_config_emulator.yaml +3 -4
  67. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_config_harvester.yaml +1 -1
  68. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_content_models.py +2 -2
  69. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/test_reader.py +8 -7
  70. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/test_writer.py +4 -4
  71. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/vsource/conftest.py +2 -2
  72. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/vsource/test_converter.py +2 -2
  73. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/vsource/test_harvester.py +1 -1
  74. shepherd_core-2025.4.1/examples/inventory.py +0 -24
  75. shepherd_core-2025.4.1/shepherd_core/commons.py +0 -8
  76. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/README.md +0 -0
  77. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/eenv_generator.py +0 -0
  78. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/experiment_from_yaml.yaml +0 -0
  79. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/firmware_model.py +0 -0
  80. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/firmware_modification.py +0 -0
  81. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/uart_decode_waveform.py +0 -0
  82. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/uart_raw2.csv +0 -0
  83. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/examples/vsource_debug_sim.py +0 -0
  84. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/setup.cfg +0 -0
  85. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/__init__.py +0 -0
  86. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/base/__init__.py +0 -0
  87. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/base/timezone.py +0 -0
  88. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/__init__.py +0 -0
  89. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -0
  90. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/content/firmware_datatype.py +0 -0
  91. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/experiment/__init__.py +0 -0
  92. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/readme.md +0 -0
  93. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/__init__.py +0 -0
  94. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/cape_fixture.yaml +0 -0
  95. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -0
  96. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/observer_fixture.yaml +0 -0
  97. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/target_fixture.old1 +0 -0
  98. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/target_fixture.yaml +0 -0
  99. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/data_models/testbed/testbed_fixture.yaml +0 -0
  100. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/decoder_waveform/__init__.py +0 -0
  101. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/fw_tools/__init__.py +0 -0
  102. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/fw_tools/converter_elf.py +0 -0
  103. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/testbed_client/__init__.py +0 -0
  104. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/testbed_client/cache_path.py +0 -0
  105. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core/vsource/__init__.py +0 -0
  106. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core.egg-info/SOURCES.txt +0 -0
  107. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core.egg-info/dependency_links.txt +0 -0
  108. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core.egg-info/requires.txt +0 -0
  109. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core.egg-info/top_level.txt +0 -0
  110. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/shepherd_core.egg-info/zip-safe +0 -0
  111. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/__init__.py +0 -0
  112. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/__init__.py +0 -0
  113. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/conftest.py +0 -0
  114. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_cal_data.yaml +0 -0
  115. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_cal_data_faulty.yaml +0 -0
  116. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_cal_meas.yaml +0 -0
  117. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_cal_meas_faulty1.yaml +0 -0
  118. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_cal_meas_faulty2.yaml +0 -0
  119. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_config_experiment.yaml +0 -0
  120. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_config_experiment_alternative.yaml +0 -0
  121. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_config_testbed.yaml +0 -0
  122. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/example_config_virtsource.yaml +0 -0
  123. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_base_models.py +0 -0
  124. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_content_fixtures.py +0 -0
  125. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_examples.py +0 -0
  126. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_experiment_models.py +0 -0
  127. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_task_generation.py +0 -0
  128. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_task_models.py +0 -0
  129. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_testbed_fixtures.py +0 -0
  130. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/data_models/test_testbed_models.py +0 -0
  131. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/decoder_waveform/__init__.py +0 -0
  132. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/decoder_waveform/test_decoder.py +0 -0
  133. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/fw_tools/__init__.py +0 -0
  134. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/fw_tools/build_msp.elf +0 -0
  135. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/fw_tools/build_nrf.elf +0 -0
  136. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/fw_tools/conftest.py +0 -0
  137. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/fw_tools/test_converter.py +0 -0
  138. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/fw_tools/test_patcher.py +0 -0
  139. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/fw_tools/test_validation.py +0 -0
  140. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/inventory/__init__.py +0 -0
  141. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/inventory/test_inventory.py +0 -0
  142. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/test_cal_hw.py +0 -0
  143. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/test_examples.py +0 -0
  144. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/test_logger.py +0 -0
  145. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/testbed_client/__init__.py +0 -0
  146. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/tests/vsource/__init__.py +0 -0
  147. {shepherd_core-2025.4.1 → shepherd_core-2025.5.2}/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.4.1
3
+ Version: 2025.5.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>
@@ -18,7 +18,6 @@ Classifier: Development Status :: 5 - Production/Stable
18
18
  Classifier: Intended Audience :: Developers
19
19
  Classifier: Intended Audience :: Information Technology
20
20
  Classifier: Intended Audience :: Science/Research
21
- Classifier: Programming Language :: Python :: 3.8
22
21
  Classifier: Programming Language :: Python :: 3.9
23
22
  Classifier: Programming Language :: Python :: 3.10
24
23
  Classifier: Programming Language :: Python :: 3.11
@@ -27,7 +26,7 @@ Classifier: Programming Language :: Python :: 3.13
27
26
  Classifier: License :: OSI Approved :: MIT License
28
27
  Classifier: Operating System :: OS Independent
29
28
  Classifier: Natural Language :: English
30
- Requires-Python: >=3.8
29
+ Requires-Python: >=3.9
31
30
  Description-Content-Type: text/markdown
32
31
  Requires-Dist: h5py
33
32
  Requires-Dist: numpy
@@ -15,13 +15,8 @@ What the code does:
15
15
 
16
16
  from pathlib import Path
17
17
 
18
+ import shepherd_core.data_models as sm
18
19
  from shepherd_core import WebClient
19
- from shepherd_core.data_models import FirmwareDType
20
- from shepherd_core.data_models import GpioTracing
21
- from shepherd_core.data_models.content import EnergyEnvironment
22
- from shepherd_core.data_models.content import Firmware
23
- from shepherd_core.data_models.experiment import Experiment
24
- from shepherd_core.data_models.experiment import TargetConfig
25
20
  from shepherd_core.data_models.task import TestbedTasks
26
21
  from shepherd_core.data_models.testbed import MCU
27
22
 
@@ -34,28 +29,26 @@ do_connect = False
34
29
  if do_connect:
35
30
  WebClient()
36
31
 
37
- xp = Experiment(
32
+ xp = sm.Experiment(
38
33
  id="4567",
39
34
  name="meaningful_TestName",
40
35
  # time_start could be "2033-03-13 14:15:16" or "datetime.now() + timedelta(minutes=30)"
41
36
  duration=30,
42
37
  target_configs=[
43
- TargetConfig(
38
+ sm.TargetConfig(
44
39
  target_IDs=range(7, 12),
45
40
  custom_IDs=range(1, 100), # note: longer list is OK
46
- energy_env=EnergyEnvironment(name="eenv_static_3000mV_50mA_3600s"),
47
- firmware1=Firmware(
41
+ energy_env=sm.EnergyEnvironment(name="eenv_static_3000mV_50mA_3600s"),
42
+ firmware1=sm.Firmware(
48
43
  name="FW_TestXYZ",
49
44
  data=Path("/var/shepherd/content/fw/nes_lab/nrf52_demo_rf/build.elf"),
50
- data_type=FirmwareDType.path_elf,
45
+ data_type=sm.FirmwareDType.path_elf,
51
46
  data_local=False,
52
47
  mcu=MCU(name="nRF52"),
53
48
  ),
54
49
  power_tracing=None,
55
- gpio_tracing=GpioTracing(
56
- uart_decode=True, # enables logging uart from userspace
57
- uart_baudrate=115_200,
58
- ),
50
+ gpio_tracing=sm.GpioTracing(),
51
+ uart_tracing=sm.UartTracing(baudrate=115_200),
59
52
  ),
60
53
  ],
61
54
  )
@@ -14,12 +14,8 @@
14
14
 
15
15
  from pathlib import Path
16
16
 
17
+ import shepherd_core.data_models as sm
17
18
  from shepherd_core import WebClient
18
- from shepherd_core.data_models import GpioTracing
19
- from shepherd_core.data_models.content import EnergyEnvironment
20
- from shepherd_core.data_models.content import Firmware
21
- from shepherd_core.data_models.experiment import Experiment
22
- from shepherd_core.data_models.experiment import TargetConfig
23
19
  from shepherd_core.data_models.task import TestbedTasks
24
20
 
25
21
  # For online-queries the lib can be connected to the testbed-server.
@@ -31,24 +27,21 @@ do_connect = False
31
27
  if do_connect:
32
28
  WebClient()
33
29
 
34
- xp = Experiment(
30
+ xp = sm.Experiment(
35
31
  id="4567",
36
32
  name="meaningful_TestName",
37
33
  # time_start could be "2033-03-13 14:15:16" or "datetime.now() + timedelta(minutes=30)"
38
34
  duration=30,
39
35
  target_configs=[
40
- TargetConfig(
36
+ sm.TargetConfig(
41
37
  target_IDs=range(7, 12),
42
38
  custom_IDs=range(1, 100), # note: longer list is OK
43
- energy_env=EnergyEnvironment(name="eenv_static_3000mV_50mA_3600s"),
44
- firmware1=Firmware.from_firmware(
39
+ energy_env=sm.EnergyEnvironment(name="eenv_static_3000mV_50mA_3600s"),
40
+ firmware1=sm.Firmware.from_firmware(
45
41
  file=Path("./firmware_nrf.elf").absolute(),
46
42
  ),
47
43
  power_tracing=None,
48
- gpio_tracing=GpioTracing(
49
- uart_decode=True, # enables logging uart from userspace
50
- uart_baudrate=115_200,
51
- ),
44
+ gpio_tracing=sm.GpioTracing(),
52
45
  ),
53
46
  ],
54
47
  )
@@ -18,17 +18,12 @@ How to define an experiment:
18
18
 
19
19
  """
20
20
 
21
+ import shepherd_core.data_models as sm
21
22
  from shepherd_core import WebClient
22
- from shepherd_core.data_models.content import EnergyEnvironment
23
- from shepherd_core.data_models.content import Firmware
24
- from shepherd_core.data_models.content import VirtualHarvesterConfig
25
- from shepherd_core.data_models.content import VirtualSourceConfig
26
- from shepherd_core.data_models.experiment import Experiment
27
- from shepherd_core.data_models.experiment import TargetConfig
28
23
  from shepherd_core.data_models.task import TestbedTasks
29
24
 
30
25
  # generate description for all parameters -> base for web-forms
31
- Experiment.schema_to_file("experiment_schema.yaml")
26
+ sm.Experiment.schema_to_file("experiment_schema.yaml")
32
27
 
33
28
  # For online-queries the lib can be connected to the testbed-server.
34
29
  # NOTE: there are 3 states:
@@ -40,11 +35,11 @@ if do_connect:
40
35
  WebClient()
41
36
 
42
37
  # Defining an Experiment in Python
43
- hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
38
+ hrv = sm.VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
44
39
 
45
40
  target_cfgs = [
46
41
  # first Instance similar to yaml-syntax
47
- TargetConfig(
42
+ sm.TargetConfig(
48
43
  target_IDs=[9, 10, 11],
49
44
  custom_IDs=[0, 1, 2],
50
45
  energy_env={"name": "SolarSunny"},
@@ -52,17 +47,17 @@ target_cfgs = [
52
47
  firmware1={"name": "nrf52_demo_rf"},
53
48
  ),
54
49
  # second Instance fully object-oriented (recommended)
55
- TargetConfig(
50
+ sm.TargetConfig(
56
51
  target_IDs=list(range(1, 5)),
57
52
  custom_IDs=list(range(7, 18)), # note: longer list is OK
58
- energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
59
- virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
60
- firmware1=Firmware(name="nrf52_demo_rf"),
61
- firmware2=Firmware(name="msp430_deep_sleep"),
53
+ energy_env=sm.EnergyEnvironment(name="ThermoelectricWashingMachine"),
54
+ virtual_source=sm.VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
55
+ firmware1=sm.Firmware(name="nrf52_demo_rf"),
56
+ firmware2=sm.Firmware(name="msp430_deep_sleep"),
62
57
  ),
63
58
  ]
64
59
 
65
- xperi1 = Experiment(
60
+ xperi1 = sm.Experiment(
66
61
  id="4567",
67
62
  name="meaningful Test-Name",
68
63
  time_start="2033-03-13 14:15:16", # or: datetime.now() + timedelta(minutes=30)
@@ -71,12 +66,12 @@ xperi1 = Experiment(
71
66
 
72
67
  # Safe, reload and compare content
73
68
  xperi1.to_file("experiment_from_py.yaml", minimal=False)
74
- xperi2 = Experiment.from_file("experiment_from_py.yaml")
69
+ xperi2 = sm.Experiment.from_file("experiment_from_py.yaml")
75
70
  print(f"xp1 hash: {xperi1.get_hash()}")
76
71
  print(f"xp2 hash: {xperi2.get_hash()}")
77
72
 
78
73
  # comparison to same config (in yaml) fails due to internal variables, BUT:
79
- xperi3 = Experiment.from_file("experiment_from_yaml.yaml")
74
+ xperi3 = sm.Experiment.from_file("experiment_from_yaml.yaml")
80
75
  print(f"xp3 hash: {xperi3.get_hash()} (won't match)")
81
76
 
82
77
  # Create a tasks-list for the testbed
@@ -0,0 +1,20 @@
1
+ """Shows how to use inventory functionality."""
2
+
3
+ from pathlib import Path
4
+
5
+ import shepherd_core.inventory as si
6
+
7
+ pyt_inv = si.PythonInventory.collect()
8
+ print(f"PyInv: {pyt_inv}")
9
+ sys_inv = si.SystemInventory.collect()
10
+ print(f"SysInv: {sys_inv}")
11
+ tgt_inv = si.TargetInventory.collect()
12
+ print(f"TgtInv: {tgt_inv}")
13
+
14
+
15
+ inv = si.Inventory.collect()
16
+ print(f"Complete Inventory: {inv}")
17
+ inv.to_file("inventory.yaml", minimal=True, comment="just a test")
18
+
19
+ inl = si.InventoryList(elements=[inv])
20
+ inl.to_csv(Path(__file__).parent / "inventory.csv")
@@ -1,6 +1,6 @@
1
1
  """Demonstrate behavior of Virtual Harvester Algorithms.
2
2
 
3
- - simulation is based on ivsamples derived from a solar-isc-voc-recording during a jogging-trip
3
+ - simulation is based on IVTrace derived from a solar-isc-voc-recording during a jogging-trip
4
4
  - harvesting is done by various algorithms and preconfigured virtual harvesters
5
5
  - results are printed on console (harvested energy)
6
6
 
@@ -44,13 +44,13 @@ save_files: bool = False
44
44
  # convert IVonne to IVCurve
45
45
  if not file_ivcurve.exists():
46
46
  with ivonne.Reader(file_ivonne) as db:
47
- db.convert_2_ivcurves(file_ivcurve, duration_s=sim_duration)
47
+ db.convert_2_ivsurface(file_ivcurve, duration_s=sim_duration)
48
48
 
49
49
  # Input Statistics
50
50
  with Reader(file_ivcurve, verbose=False) as file:
51
51
  window_size = file.get_window_samples()
52
52
  I_in_max = 0.0
53
- for _t, _v, _i in file.read_buffers():
53
+ for _t, _v, _i in file.read():
54
54
  I_in_max = max(I_in_max, _i.max())
55
55
  print(
56
56
  f"Input-file: \n"
@@ -61,11 +61,7 @@ with Reader(file_ivcurve, verbose=False) as file:
61
61
 
62
62
  # Simulation
63
63
  for hrv_name in hrv_list:
64
- file_output = (
65
- file_ivcurve.with_name(file_ivcurve.stem + "_" + hrv_name + file_ivcurve.suffix)
66
- if save_files
67
- else None
68
- )
64
+ file_output = file_ivcurve.with_stem(file_ivcurve.stem + "_" + hrv_name) if save_files else None
69
65
  E_out_Ws = simulate_harvester(
70
66
  config=VirtualHarvesterConfig(name=hrv_name),
71
67
  path_input=file_ivcurve,
@@ -42,11 +42,7 @@ tgt = ResistiveTarget(R_Ohm=1_000, controlled=True)
42
42
  save_files = True
43
43
 
44
44
  for src_name in src_list:
45
- file_output = (
46
- file_input.with_name(file_input.stem + "_emu_" + src_name + file_input.suffix)
47
- if save_files
48
- else None
49
- )
45
+ file_output = file_input.with_stem(file_input.stem + "_emu_" + src_name) if save_files else None
50
46
 
51
47
  e_out_Ws = simulate_source(
52
48
  config=VirtualSourceConfig(
@@ -14,7 +14,6 @@ classifiers = [
14
14
  "Intended Audience :: Developers",
15
15
  "Intended Audience :: Information Technology",
16
16
  "Intended Audience :: Science/Research",
17
- "Programming Language :: Python :: 3.8",
18
17
  "Programming Language :: Python :: 3.9",
19
18
  "Programming Language :: Python :: 3.10",
20
19
  "Programming Language :: Python :: 3.11",
@@ -25,7 +24,7 @@ classifiers = [
25
24
  "Natural Language :: English",
26
25
  ]
27
26
 
28
- requires-python = ">=3.8"
27
+ requires-python = ">=3.9"
29
28
  dependencies = [
30
29
  "h5py",
31
30
  "numpy",
@@ -111,6 +110,10 @@ source = ["shepherd_core"]
111
110
  omit = ["*/shepherd_data/*"]
112
111
 
113
112
  [tool.mypy]
114
- python_version = 3.8
113
+ python_version = 3.9
115
114
  ignore_missing_imports = true
116
115
  disable_error_code = ["call-arg", ]
116
+ exclude = [
117
+ "build/",
118
+ ".egg-info/",
119
+ ]
@@ -10,26 +10,26 @@ currently configured for cape v2.4c
10
10
  """
11
11
 
12
12
  # both current channels have a 0.1 % shunt resistance of
13
- R_SHT = 2.0 # [ohm]
13
+ R_SHT: float = 2.0 # [ohm]
14
14
  # the instrumentation amplifiers are configured for gain of
15
- G_INST_AMP = 48 # [n]
15
+ G_INST_AMP: int = 48 # [n]
16
16
  # we use the ADC's internal reference with
17
- V_REF_ADC = 4.096 # [V]
17
+ V_REF_ADC: float = 4.096 # [V]
18
18
  # range of current channels is
19
- G_ADC_I = 1.25 # [gain / V_REF]
19
+ G_ADC_I: float = 1.25 # [gain / V_REF]
20
20
  # range of voltage channels is
21
- G_ADC_V = 1.25 # [gain / V_REF]
21
+ G_ADC_V: float = 1.25 # [gain / V_REF]
22
22
  # bit resolution of ADC
23
- M_ADC = 18 # [bit]
23
+ M_ADC: int = 18 # [bit]
24
24
  # DACs use internal reference with
25
- V_REF_DAC = 2.5 # [V]
25
+ V_REF_DAC: float = 2.5 # [V]
26
26
  # gain of DAC is set to
27
- G_DAC = 2 # [n]
27
+ G_DAC: int = 2 # [n]
28
28
  # bit resolution of DAC
29
- M_DAC = 16 # [bit]
29
+ M_DAC: int = 16 # [bit]
30
30
  # DERIVED VARIABLES
31
- RAW_MAX_ADC = 2**M_ADC - 1
32
- RAW_MAX_DAC = 2**M_DAC - 1
31
+ RAW_MAX_ADC: int = 2**M_ADC - 1
32
+ RAW_MAX_DAC: int = 2**M_DAC - 1
33
33
 
34
34
 
35
35
  def adc_current_to_raw(current: float, *, limited: bool = True) -> int:
@@ -0,0 +1,8 @@
1
+ """Container for commonly shared constants."""
2
+
3
+ SAMPLERATE_SPS_DEFAULT: int = 100_000
4
+
5
+ UID_NAME: str = "SHEPHERD_NODE_ID"
6
+ UID_SIZE: int = 2
7
+
8
+ TESTBED_SERVER_URI: str = "http://127.0.0.1:8000/shepherd"
@@ -31,6 +31,7 @@ from .experiment.observer_features import GpioLevel
31
31
  from .experiment.observer_features import GpioTracing
32
32
  from .experiment.observer_features import PowerTracing
33
33
  from .experiment.observer_features import SystemLogging
34
+ from .experiment.observer_features import UartTracing
34
35
  from .experiment.target_config import TargetConfig
35
36
 
36
37
  __all__ = [
@@ -54,6 +55,7 @@ __all__ = [
54
55
  "ShpModel",
55
56
  "SystemLogging",
56
57
  "TargetConfig",
58
+ "UartTracing",
57
59
  "VirtualHarvesterConfig",
58
60
  "VirtualSourceConfig",
59
61
  "Wrapper",
@@ -1,13 +1,12 @@
1
1
  """Models for the process of calibration a device by measurements."""
2
2
 
3
- from typing import List
3
+ from typing import Annotated
4
4
  from typing import Optional
5
5
 
6
6
  import numpy as np
7
7
  from pydantic import Field
8
8
  from pydantic import PositiveFloat
9
9
  from pydantic import validate_call
10
- from typing_extensions import Annotated
11
10
 
12
11
  from .calibration import CalibrationCape
13
12
  from .calibration import CalibrationEmulator
@@ -24,7 +23,7 @@ class CalMeasurementPair(ShpModel):
24
23
  reference_si: float = 0
25
24
 
26
25
 
27
- CalMeasPairs = Annotated[List[CalMeasurementPair], Field(min_length=2)]
26
+ CalMeasPairs = Annotated[list[CalMeasurementPair], Field(min_length=2)]
28
27
 
29
28
 
30
29
  @validate_call
@@ -37,16 +36,16 @@ def meas_to_cal(data: CalMeasPairs, component: str) -> CalibrationPair:
37
36
  y[i] = pair.reference_si
38
37
 
39
38
  model = np.polyfit(x, y, 1)
40
- offset = model[1]
41
- gain = model[0]
39
+ offset: float = float(model[1])
40
+ gain: float = float(model[0])
42
41
 
43
42
  # r-squared, Pearson correlation coefficient
44
- p = np.poly1d(model)
45
- yhat = p(x)
46
- ybar = np.sum(y) / len(y)
47
- ssreg = np.sum((yhat - ybar) ** 2)
48
- sstot = np.sum((y - ybar) ** 2)
49
- rval = ssreg / sstot
43
+ _p = np.poly1d(model)
44
+ yhat = _p(x)
45
+ ybar: float = np.sum(y) / len(y)
46
+ ssreg: float = np.sum((yhat - ybar) ** 2)
47
+ sstot: float = np.sum((y - ybar) ** 2)
48
+ rval: float = ssreg / sstot
50
49
 
51
50
  if rval < 0.999:
52
51
  msg = (
@@ -1,11 +1,11 @@
1
1
  """Models for the calibration-data to convert between raw & SI-Values."""
2
2
 
3
3
  import struct
4
+ from collections.abc import Generator
5
+ from collections.abc import Mapping
6
+ from collections.abc import Sequence
4
7
  from typing import Callable
5
- from typing import Generator
6
- from typing import Mapping
7
8
  from typing import Optional
8
- from typing import Sequence
9
9
  from typing import TypeVar
10
10
  from typing import Union
11
11
 
@@ -18,9 +18,10 @@ from pydantic import constr
18
18
  from pydantic import validate_call
19
19
  from typing_extensions import Self
20
20
 
21
- from ...calibration_hw_def import adc_current_to_raw
22
- from ...calibration_hw_def import adc_voltage_to_raw
23
- from ...calibration_hw_def import dac_voltage_to_raw
21
+ from shepherd_core.calibration_hw_def import adc_current_to_raw
22
+ from shepherd_core.calibration_hw_def import adc_voltage_to_raw
23
+ from shepherd_core.calibration_hw_def import dac_voltage_to_raw
24
+
24
25
  from .shepherd import ShpModel
25
26
  from .timezone import local_iso_date
26
27
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  import hashlib
4
4
  from datetime import datetime
5
+ from typing import Annotated
5
6
  from typing import Optional
6
7
  from typing import Union
7
8
  from uuid import uuid4
@@ -10,7 +11,6 @@ from pydantic import UUID4
10
11
  from pydantic import Field
11
12
  from pydantic import StringConstraints
12
13
  from pydantic import model_validator
13
- from typing_extensions import Annotated
14
14
  from typing_extensions import Self
15
15
  from typing_extensions import deprecated
16
16
 
@@ -2,11 +2,11 @@
2
2
 
3
3
  import hashlib
4
4
  import pathlib
5
+ from collections.abc import Generator
5
6
  from datetime import timedelta
6
7
  from ipaddress import IPv4Address
7
8
  from pathlib import Path
8
9
  from typing import Any
9
- from typing import Generator
10
10
  from typing import Optional
11
11
  from typing import Union
12
12
  from uuid import UUID
@@ -15,27 +15,26 @@ import yaml
15
15
  from pydantic import BaseModel
16
16
  from pydantic import ConfigDict
17
17
  from typing_extensions import Self
18
- from yaml import Dumper
18
+ from yaml import Node
19
19
  from yaml import SafeDumper
20
- from yaml import ScalarNode
21
20
 
22
21
  from .timezone import local_now
23
22
  from .wrapper import Wrapper
24
23
 
25
24
 
26
25
  def path2str(
27
- dumper: Dumper, data: Union[pathlib.Path, pathlib.WindowsPath, pathlib.PosixPath]
28
- ) -> ScalarNode:
26
+ dumper: SafeDumper, data: Union[pathlib.Path, pathlib.WindowsPath, pathlib.PosixPath]
27
+ ) -> Node:
29
28
  """Add a yaml-representation for a specific datatype."""
30
29
  return dumper.represent_scalar("tag:yaml.org,2002:str", str(data.as_posix()))
31
30
 
32
31
 
33
- def time2int(dumper: Dumper, data: timedelta) -> ScalarNode:
32
+ def time2int(dumper: SafeDumper, data: timedelta) -> Node:
34
33
  """Add a yaml-representation for a specific datatype."""
35
34
  return dumper.represent_scalar("tag:yaml.org,2002:int", str(int(data.total_seconds())))
36
35
 
37
36
 
38
- def generic2str(dumper: Dumper, data: Any) -> ScalarNode:
37
+ def generic2str(dumper: SafeDumper, data: Any) -> Node:
39
38
  """Add a yaml-representation for a specific datatype."""
40
39
  return dumper.represent_scalar("tag:yaml.org,2002:str", str(data))
41
40
 
@@ -1,13 +1,13 @@
1
1
  """Wrapper-related ecosystem for transferring models."""
2
2
 
3
3
  from datetime import datetime
4
+ from typing import Annotated
4
5
  from typing import Optional
5
6
 
6
7
  from pydantic import BaseModel
7
8
  from pydantic import StringConstraints
8
- from typing_extensions import Annotated
9
9
 
10
- from ...version import version
10
+ from shepherd_core.version import version
11
11
 
12
12
  SafeStrClone = Annotated[str, StringConstraints(pattern=r"^[ -~]+$")]
13
13
  # ⤷ copy avoids circular import