shepherd-core 2024.7.1__tar.gz → 2024.7.3__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 (140) hide show
  1. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/PKG-INFO +1 -1
  2. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/experiment_generic_var1.py +6 -8
  3. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/experiment_generic_var2.py +6 -8
  4. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/experiment_models.py +6 -8
  5. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/firmware_model.py +2 -4
  6. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/vharvester_simulation.py +0 -12
  7. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/vsource_simulation.py +6 -8
  8. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/pyproject.toml +1 -1
  9. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/__init__.py +4 -5
  10. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/base/wrapper.py +4 -0
  11. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/energy_environment.py +1 -1
  12. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/firmware.py +1 -0
  13. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/experiment/experiment.py +8 -7
  14. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/task/testbed_tasks.py +3 -2
  15. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/testbed.py +9 -0
  16. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/inventory/system.py +7 -6
  17. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/reader.py +10 -3
  18. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/testbed_client/__init__.py +3 -1
  19. shepherd_core-2024.7.3/shepherd_core/testbed_client/client_abc_fix.py +126 -0
  20. shepherd_core-2024.7.3/shepherd_core/testbed_client/client_web.py +157 -0
  21. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/testbed_client/fixtures.py +14 -8
  22. shepherd_core-2024.7.3/shepherd_core/version.py +3 -0
  23. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core.egg-info/PKG-INFO +1 -1
  24. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core.egg-info/SOURCES.txt +3 -1
  25. shepherd_core-2024.7.1/shepherd_core/testbed_client/client.py +0 -161
  26. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/README.md +0 -0
  27. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/experiment_from_yaml.yaml +0 -0
  28. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/firmware_modification.py +0 -0
  29. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/inventory.py +0 -0
  30. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/uart_decode_waveform.py +0 -0
  31. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/examples/uart_raw2.csv +0 -0
  32. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/setup.cfg +0 -0
  33. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/calibration_hw_def.py +0 -0
  34. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/commons.py +0 -0
  35. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/__init__.py +0 -0
  36. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/base/__init__.py +0 -0
  37. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/base/cal_measurement.py +0 -0
  38. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/base/calibration.py +0 -0
  39. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/base/content.py +0 -0
  40. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/base/shepherd.py +0 -0
  41. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/base/timezone.py +0 -0
  42. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/__init__.py +0 -0
  43. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/_external_fixtures.yaml +0 -0
  44. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -0
  45. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/firmware_datatype.py +0 -0
  46. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/virtual_harvester.py +0 -0
  47. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/virtual_harvester_fixture.yaml +0 -0
  48. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/virtual_source.py +0 -0
  49. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/content/virtual_source_fixture.yaml +0 -0
  50. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/experiment/__init__.py +0 -0
  51. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/experiment/observer_features.py +0 -0
  52. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/experiment/target_config.py +0 -0
  53. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/readme.md +0 -0
  54. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/task/__init__.py +0 -0
  55. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/task/emulation.py +0 -0
  56. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/task/firmware_mod.py +0 -0
  57. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/task/harvest.py +0 -0
  58. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/task/observer_tasks.py +0 -0
  59. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/task/programming.py +0 -0
  60. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/__init__.py +0 -0
  61. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/cape.py +0 -0
  62. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/cape_fixture.yaml +0 -0
  63. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/gpio.py +0 -0
  64. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -0
  65. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/mcu.py +0 -0
  66. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/mcu_fixture.yaml +0 -0
  67. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/observer.py +0 -0
  68. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/observer_fixture.yaml +0 -0
  69. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/target.py +0 -0
  70. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/target_fixture.yaml +0 -0
  71. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/testbed/testbed_fixture.yaml +0 -0
  72. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/data_models/virtual_source_doc.txt +0 -0
  73. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/decoder_waveform/__init__.py +0 -0
  74. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/decoder_waveform/uart.py +0 -0
  75. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/fw_tools/__init__.py +0 -0
  76. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/fw_tools/converter.py +0 -0
  77. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/fw_tools/converter_elf.py +0 -0
  78. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/fw_tools/patcher.py +0 -0
  79. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/fw_tools/validation.py +0 -0
  80. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/inventory/__init__.py +0 -0
  81. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/inventory/python.py +0 -0
  82. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/inventory/target.py +0 -0
  83. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/logger.py +0 -0
  84. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/testbed_client/cache_path.py +0 -0
  85. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/testbed_client/user_model.py +0 -0
  86. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/vsource/__init__.py +0 -0
  87. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/vsource/virtual_converter_model.py +0 -0
  88. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/vsource/virtual_harvester_model.py +0 -0
  89. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/vsource/virtual_source_model.py +0 -0
  90. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core/writer.py +0 -0
  91. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core.egg-info/dependency_links.txt +0 -0
  92. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core.egg-info/requires.txt +0 -0
  93. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core.egg-info/top_level.txt +0 -0
  94. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/shepherd_core.egg-info/zip-safe +0 -0
  95. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/__init__.py +0 -0
  96. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/conftest.py +0 -0
  97. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/__init__.py +0 -0
  98. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/conftest.py +0 -0
  99. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_cal_data.yaml +0 -0
  100. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_cal_data_faulty.yaml +0 -0
  101. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_cal_meas.yaml +0 -0
  102. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_cal_meas_faulty1.yaml +0 -0
  103. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_cal_meas_faulty2.yaml +0 -0
  104. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_config_emulator.yaml +0 -0
  105. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_config_experiment.yaml +0 -0
  106. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_config_experiment_alternative.yaml +0 -0
  107. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_config_harvester.yaml +0 -0
  108. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_config_testbed.yaml +0 -0
  109. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/example_config_virtsource.yaml +0 -0
  110. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_base_models.py +0 -0
  111. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_content_fixtures.py +0 -0
  112. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_content_models.py +0 -0
  113. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_examples.py +0 -0
  114. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_experiment_models.py +0 -0
  115. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_task_generation.py +0 -0
  116. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_task_models.py +0 -0
  117. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_testbed_fixtures.py +0 -0
  118. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/data_models/test_testbed_models.py +0 -0
  119. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/decoder_waveform/__init__.py +0 -0
  120. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/decoder_waveform/test_decoder.py +0 -0
  121. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/fw_tools/__init__.py +0 -0
  122. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/fw_tools/build_msp.elf +0 -0
  123. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/fw_tools/build_nrf.elf +0 -0
  124. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/fw_tools/conftest.py +0 -0
  125. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/fw_tools/test_converter.py +0 -0
  126. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/fw_tools/test_patcher.py +0 -0
  127. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/fw_tools/test_validation.py +0 -0
  128. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/inventory/__init__.py +0 -0
  129. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/inventory/test_inventory.py +0 -0
  130. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/test_cal_hw.py +0 -0
  131. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/test_examples.py +0 -0
  132. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/test_logger.py +0 -0
  133. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/test_reader.py +0 -0
  134. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/test_writer.py +0 -0
  135. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/testbed_client/__init__.py +0 -0
  136. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/vsource/__init__.py +0 -0
  137. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/vsource/conftest.py +0 -0
  138. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/vsource/test_converter.py +0 -0
  139. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/vsource/test_harvester.py +0 -0
  140. {shepherd_core-2024.7.1 → shepherd_core-2024.7.3}/tests/vsource/test_z.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: shepherd_core
3
- Version: 2024.7.1
3
+ Version: 2024.7.3
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>
@@ -15,7 +15,7 @@ What the code does:
15
15
 
16
16
  from pathlib import Path
17
17
 
18
- from shepherd_core import TestbedClient
18
+ from shepherd_core import WebClient
19
19
  from shepherd_core.data_models import FirmwareDType
20
20
  from shepherd_core.data_models import GpioTracing
21
21
  from shepherd_core.data_models.content import EnergyEnvironment
@@ -25,16 +25,14 @@ from shepherd_core.data_models.experiment import TargetConfig
25
25
  from shepherd_core.data_models.task import TestbedTasks
26
26
  from shepherd_core.data_models.testbed import MCU
27
27
 
28
- # for online-queries the lib can be connected to the testbed-server
28
+ # For online-queries the lib can be connected to the testbed-server.
29
29
  # NOTE: there are 3 states:
30
- # - unconnected -> demo-fixture is queried (locally)
31
- # - connected -> publicly available data is queried online
32
- # - logged in with token -> also private data is queried online
33
- tb_client = TestbedClient()
30
+ # - unconnected -> demo-fixtures are queried (locally)
31
+ # - connected -> publicly available data is queried online
32
+ # - logged in with valid token -> also private data is queried online
34
33
  do_connect = False
35
-
36
34
  if do_connect:
37
- tb_client.connect()
35
+ WebClient()
38
36
 
39
37
  xp = Experiment(
40
38
  id="4567",
@@ -14,7 +14,7 @@
14
14
 
15
15
  from pathlib import Path
16
16
 
17
- from shepherd_core import TestbedClient
17
+ from shepherd_core import WebClient
18
18
  from shepherd_core.data_models import GpioTracing
19
19
  from shepherd_core.data_models.content import EnergyEnvironment
20
20
  from shepherd_core.data_models.content import Firmware
@@ -22,16 +22,14 @@ from shepherd_core.data_models.experiment import Experiment
22
22
  from shepherd_core.data_models.experiment import TargetConfig
23
23
  from shepherd_core.data_models.task import TestbedTasks
24
24
 
25
- # for online-queries the lib can be connected to the testbed-server
25
+ # For online-queries the lib can be connected to the testbed-server.
26
26
  # NOTE: there are 3 states:
27
- # - unconnected -> demo-fixture is queried (locally)
28
- # - connected -> publicly available data is queried online
29
- # - logged in with token -> also private data is queried online
30
- tb_client = TestbedClient()
27
+ # - unconnected -> demo-fixtures are queried (locally)
28
+ # - connected -> publicly available data is queried online
29
+ # - logged in with valid token -> also private data is queried online
31
30
  do_connect = False
32
-
33
31
  if do_connect:
34
- tb_client.connect()
32
+ WebClient()
35
33
 
36
34
  xp = Experiment(
37
35
  id="4567",
@@ -18,7 +18,7 @@ How to define an experiment:
18
18
 
19
19
  """
20
20
 
21
- from shepherd_core import TestbedClient
21
+ from shepherd_core import WebClient
22
22
  from shepherd_core.data_models.content import EnergyEnvironment
23
23
  from shepherd_core.data_models.content import Firmware
24
24
  from shepherd_core.data_models.content import VirtualHarvesterConfig
@@ -30,16 +30,14 @@ from shepherd_core.data_models.task import TestbedTasks
30
30
  # generate description for all parameters -> base for web-forms
31
31
  Experiment.schema_to_file("experiment_schema.yaml")
32
32
 
33
- # for online-queries the lib can be connected to the testbed-server
33
+ # For online-queries the lib can be connected to the testbed-server.
34
34
  # NOTE: there are 3 states:
35
- # - unconnected -> demo-fixture is queried (locally)
36
- # - connected -> publicly available data is queried online
37
- # - logged in with token -> also private data is queried online
38
- tb_client = TestbedClient()
35
+ # - unconnected -> demo-fixtures are queried (locally)
36
+ # - connected -> publicly available data is queried online
37
+ # - logged in with valid token -> also private data is queried online
39
38
  do_connect = False
40
-
41
39
  if do_connect:
42
- tb_client.connect()
40
+ WebClient()
43
41
 
44
42
  # Defining an Experiment in Python
45
43
  hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
@@ -6,7 +6,7 @@ or shepherd-core[elf].
6
6
 
7
7
  from pathlib import Path
8
8
 
9
- from shepherd_core import TestbedClient
9
+ from shepherd_core import WebClient
10
10
  from shepherd_core import fw_tools
11
11
  from shepherd_core.data_models import Firmware
12
12
  from shepherd_core.data_models import FirmwareDType
@@ -41,9 +41,7 @@ print(f"stored firmware to '{path_elf2.name}'")
41
41
 
42
42
  # Option 3 - fully automatic (with login) -> owner and group get prefilled
43
43
 
44
- tb_client = TestbedClient()
45
44
  do_connect = False
46
-
47
45
  if do_connect:
48
- tb_client.connect(token="your_personal_login_token") # noqa: S106
46
+ WebClient(token="your_personal_login_token") # noqa: S106
49
47
  fw3 = Firmware.from_firmware(file=path_elf, name="msp_deep_sleep3")
@@ -9,7 +9,6 @@
9
9
  from pathlib import Path
10
10
 
11
11
  from shepherd_core import Reader
12
- from shepherd_core import TestbedClient
13
12
  from shepherd_core.data_models import VirtualHarvesterConfig
14
13
  from shepherd_core.data_models.content.virtual_harvester import HarvesterPRUConfig
15
14
  from shepherd_core.vsource import VirtualHarvesterModel
@@ -33,17 +32,6 @@ hrv_list = [
33
32
  "mppt_opt",
34
33
  ]
35
34
 
36
- # for online-queries the lib can be connected to the testbed-server
37
- # NOTE: there are 3 states:
38
- # - unconnected -> demo-fixture is queried (locally)
39
- # - connected -> publicly available data is queried online
40
- # - logged in with token -> also private data is queried online
41
- tb_client = TestbedClient()
42
- do_connect = False
43
-
44
- if do_connect:
45
- tb_client.connect()
46
-
47
35
  # convert IVonne to IVCurve
48
36
  if not file_ivcurve.exists():
49
37
  with ivonne.Reader(file_ivonne) as db:
@@ -16,7 +16,7 @@ import matplotlib.pyplot as plt
16
16
  import numpy as np
17
17
 
18
18
  from shepherd_core import CalibrationEmulator
19
- from shepherd_core import TestbedClient
19
+ from shepherd_core import WebClient
20
20
  from shepherd_core.data_models import VirtualSourceConfig
21
21
  from shepherd_core.vsource import VirtualSourceModel
22
22
 
@@ -38,16 +38,14 @@ src_list = [
38
38
  I_mcu_sleep_A = 200e-9
39
39
  I_mcu_active_A = 1e-3
40
40
 
41
- # for online-queries the lib can be connected to the testbed-server
41
+ # For online-queries the lib can be connected to the testbed-server.
42
42
  # NOTE: there are 3 states:
43
- # - unconnected -> demo-fixture is queried (locally)
44
- # - connected -> publicly available data is queried online
45
- # - logged in with token -> also private data is queried online
46
- tb_client = TestbedClient()
43
+ # - unconnected -> demo-fixtures are queried (locally)
44
+ # - connected -> publicly available data is queried online
45
+ # - logged in with valid token -> also private data is queried online
47
46
  do_connect = False
48
-
49
47
  if do_connect:
50
- tb_client.connect()
48
+ WebClient()
51
49
 
52
50
  for vs_name, v_hrv_mV, samples in product(src_list, v_hrv_mV_list, sample_dur_list):
53
51
  # prepare simulation
@@ -94,7 +94,7 @@ shepherd_core = [
94
94
  ]
95
95
 
96
96
  [tool.setuptools.dynamic]
97
- version = {attr = "shepherd_core.__version__"}
97
+ version = {attr = "shepherd_core.version.version"}
98
98
 
99
99
  [tool.pytest.ini_options]
100
100
  markers = [
@@ -19,11 +19,11 @@ from .logger import get_verbose_level
19
19
  from .logger import increase_verbose_level
20
20
  from .logger import logger
21
21
  from .reader import Reader
22
- from .testbed_client.client import TestbedClient
23
- from .testbed_client.client import tb_client
22
+ from .testbed_client.client_web import WebClient
23
+ from .version import version
24
24
  from .writer import Writer
25
25
 
26
- __version__ = "2024.7.1"
26
+ __version__ = version
27
27
 
28
28
  __all__ = [
29
29
  "Reader",
@@ -40,7 +40,6 @@ __all__ = [
40
40
  "local_now",
41
41
  "Calc_t",
42
42
  "Compression",
43
- "TestbedClient",
44
- "tb_client", # using this (instead of the Class) is the cleaner, but less pythonic way
43
+ "WebClient",
45
44
  "Inventory",
46
45
  ]
@@ -7,6 +7,8 @@ from pydantic import BaseModel
7
7
  from pydantic import StringConstraints
8
8
  from typing_extensions import Annotated
9
9
 
10
+ from ...version import version
11
+
10
12
  SafeStrClone = Annotated[str, StringConstraints(pattern=r"^[ -~]+$")]
11
13
  # ⤷ copy avoids circular import
12
14
 
@@ -19,5 +21,7 @@ class Wrapper(BaseModel):
19
21
  comment: Optional[SafeStrClone] = None
20
22
  created: Optional[datetime] = None
21
23
  # ⤷ Optional metadata
24
+ lib_ver: Optional[str] = version
25
+ # ⤷ for debug-purposes and later comp-checks
22
26
  parameters: dict
23
27
  # ⤷ ShpModel
@@ -35,7 +35,7 @@ class EnergyEnvironment(ContentModel):
35
35
 
36
36
  # TODO: scale up/down voltage/current
37
37
 
38
- # additional descriptive metadata
38
+ # additional descriptive metadata, TODO: these are very solar-centered -> generalize
39
39
  light_source: Optional[str] = None
40
40
  weather_conditions: Optional[str] = None
41
41
  indoor: Optional[bool] = None
@@ -152,6 +152,7 @@ class Firmware(ContentModel, title="Firmware of Target"):
152
152
 
153
153
  if not match:
154
154
  logger.warning("FW-Hash does not match with stored value!")
155
+ # TODO: it might be more appropriate to raise here
155
156
  return match
156
157
 
157
158
  @validate_call
@@ -13,6 +13,7 @@ from pydantic import model_validator
13
13
  from typing_extensions import Annotated
14
14
  from typing_extensions import Self
15
15
 
16
+ from ...version import version
16
17
  from ..base.content import IdInt
17
18
  from ..base.content import NameStr
18
19
  from ..base.content import SafeStr
@@ -54,18 +55,20 @@ class Experiment(ShpModel, title="Config of an Experiment"):
54
55
  # targets
55
56
  target_configs: Annotated[List[TargetConfig], Field(min_length=1, max_length=128)]
56
57
 
57
- # TODO: we probably need to remember the lib-version for content &| experiment
58
+ # for debug-purposes and later comp-checks
59
+ lib_ver: Optional[str] = version
58
60
 
59
61
  @model_validator(mode="after")
60
62
  def post_validation(self) -> Self:
61
- self.validate_targets(self.target_configs)
62
- self.validate_observers(self.target_configs)
63
+ testbed = Testbed() # this will query the first (and only) entry of client
64
+ self._validate_targets(self.target_configs)
65
+ self._validate_observers(self.target_configs, testbed)
63
66
  if self.duration and self.duration.total_seconds() < 0:
64
67
  raise ValueError("Duration of experiment can't be negative.")
65
68
  return self
66
69
 
67
70
  @staticmethod
68
- def validate_targets(configs: List[TargetConfig]) -> None:
71
+ def _validate_targets(configs: List[TargetConfig]) -> None:
69
72
  target_ids = []
70
73
  custom_ids = []
71
74
  for _config in configs:
@@ -83,10 +86,8 @@ class Experiment(ShpModel, title="Config of an Experiment"):
83
86
  raise ValueError("Custom Target-ID are faulty (some form of id-collisions)!")
84
87
 
85
88
  @staticmethod
86
- def validate_observers(configs: List[TargetConfig]) -> None:
89
+ def _validate_observers(configs: List[TargetConfig], testbed: Testbed) -> None:
87
90
  target_ids = [_id for _config in configs for _id in _config.target_IDs]
88
-
89
- testbed = Testbed(name="shepherd_tud_nes")
90
91
  obs_ids = [testbed.get_observer(_id).id for _id in target_ids]
91
92
  if len(target_ids) > len(set(obs_ids)):
92
93
  raise ValueError(
@@ -32,8 +32,9 @@ class TestbedTasks(ShpModel):
32
32
  @validate_call
33
33
  def from_xp(cls, xp: Experiment, tb: Optional[Testbed] = None) -> Self:
34
34
  if tb is None:
35
- # TODO: just for testing OK
36
- tb = Testbed(name="shepherd_tud_nes")
35
+ # TODO: is tb-argument really needed? prob. not
36
+ tb = Testbed() # this will query the first (and only) entry of client
37
+
37
38
  tgt_ids = xp.get_target_ids()
38
39
  obs_tasks = [ObserverTasks.from_xp(xp, tb, _id) for _id in tgt_ids]
39
40
  return cls(
@@ -11,6 +11,7 @@ from pydantic import model_validator
11
11
  from typing_extensions import Annotated
12
12
  from typing_extensions import Self
13
13
 
14
+ from ... import logger
14
15
  from ...testbed_client import tb_client
15
16
  from ..base.content import IdInt
16
17
  from ..base.content import NameStr
@@ -42,6 +43,14 @@ class Testbed(ShpModel):
42
43
  @model_validator(mode="before")
43
44
  @classmethod
44
45
  def query_database(cls, values: dict) -> dict:
46
+ # allow instantiating an empty Testbed
47
+ # -> query the first (and only) entry of client
48
+ if len(values) == 0:
49
+ ids = tb_client.query_ids(cls.__name__)
50
+ if len(ids) > 1:
51
+ logger.warning("More than one testbed defined?!?")
52
+ values = {"id": ids[0]}
53
+
45
54
  values, _ = tb_client.try_completing_model(cls.__name__, values)
46
55
  return values
47
56
 
@@ -5,6 +5,7 @@ import subprocess
5
5
  import time
6
6
  from datetime import datetime
7
7
  from pathlib import Path
8
+ from typing import List
8
9
  from typing import Optional
9
10
 
10
11
  from typing_extensions import Self
@@ -48,8 +49,8 @@ class SystemInventory(ShpModel):
48
49
  # ip IPvAnyAddress
49
50
  # mac MACStr
50
51
 
51
- fs_root: Optional[str] = None
52
- beagle: Optional[str] = None
52
+ fs_root: List[str] = None
53
+ beagle: List[str] = None
53
54
 
54
55
  model_config = ConfigDict(str_min_length=0)
55
56
 
@@ -71,20 +72,20 @@ class SystemInventory(ShpModel):
71
72
  uptime = time.time() - psutil.boot_time()
72
73
 
73
74
  fs_cmd = ["/usr/bin/df", "-h", "/"]
74
- fs_out = None
75
+ fs_out = []
75
76
  if Path(fs_cmd[0]).is_file():
76
77
  reply = subprocess.run( # noqa: S603
77
78
  fs_cmd, timeout=30, capture_output=True, check=False
78
79
  )
79
- fs_out = str(reply.stdout)
80
+ fs_out = str(reply.stdout).split(r"\n")
80
81
 
81
82
  beagle_cmd = ["/usr/bin/beagle-version"]
82
- beagle_out = None
83
+ beagle_out = []
83
84
  if Path(beagle_cmd[0]).is_file():
84
85
  reply = subprocess.run( # noqa: S603
85
86
  beagle_cmd, timeout=30, capture_output=True, check=False
86
87
  )
87
- beagle_out = str(reply.stdout)
88
+ beagle_out = str(reply.stdout).split(r"\n")
88
89
 
89
90
  ptp_cmd = ["/usr/sbin/ptp4l", "-v"]
90
91
  ptp_out = None
@@ -536,9 +536,9 @@ class Reader:
536
536
  def count_errors_in_log(self, group_name: str = "sheep", min_level: int = 40) -> int:
537
537
  if group_name not in self.h5file:
538
538
  return 0
539
- if "level" not in self.h5file["sheep"]:
539
+ if "level" not in self.h5file[group_name]:
540
540
  return 0
541
- _lvl = self.h5file["sheep"]["level"]
541
+ _lvl = self.h5file[group_name]["level"]
542
542
  if _lvl.shape[0] < 1:
543
543
  return 0
544
544
  _items = [1 for _x in _lvl[:] if _x >= min_level]
@@ -688,4 +688,11 @@ class Reader:
688
688
  gpio_wf = pin_wf.astype(float)
689
689
  gpio_wf[:, 0] = gpio_wf[:, 0] / 1e9
690
690
 
691
- return Uart(gpio_wf).get_lines()
691
+ try:
692
+ return Uart(gpio_wf).get_lines()
693
+ except TypeError:
694
+ self._logger.error("TypeError: Extracting UART from GPIO failed - will skip file.")
695
+ return None
696
+ except ValueError:
697
+ self._logger.error("ValueError: Extracting UART from GPIO failed - will skip file.")
698
+ return None
@@ -1,9 +1,11 @@
1
1
  """Client to access a testbed-instance for controlling experiments."""
2
2
 
3
- from .client import tb_client
3
+ from .client_abc_fix import tb_client
4
+ from .client_web import WebClient
4
5
  from .user_model import User
5
6
 
6
7
  __all__ = [
7
8
  "tb_client",
9
+ "WebClient",
8
10
  "User",
9
11
  ]
@@ -0,0 +1,126 @@
1
+ """AbstractBase-Class & Client-Class to access the file based fixtures.
2
+
3
+ Fixtures == OffLineDemoInstances
4
+ offline: core - fixtClient
5
+ webDev: core - webClient <-> webSrv - fixtClient
6
+ webUser: core - webClient <-> webSrv - DbClient
7
+ webInfra: core - webClient+ <-> webSrv - DbClient
8
+
9
+ Users, Sheep and ServerApps should have access to the same DB via WebClient
10
+
11
+ Note: ABC and FixClient can't be in separate files when tb_client should
12
+ default to FixClient (circular import)
13
+
14
+ TODO: Comfort functions missing
15
+ - fixtures to DB, and vice versa
16
+ """
17
+
18
+ from abc import ABC
19
+ from abc import abstractmethod
20
+ from typing import List
21
+ from typing import Optional
22
+
23
+ from ..data_models.base.shepherd import ShpModel
24
+ from ..data_models.base.wrapper import Wrapper
25
+ from .fixtures import Fixtures
26
+
27
+
28
+ class AbcClient(ABC):
29
+ """AbstractBase-Class to access a testbed instance."""
30
+
31
+ def __init__(self) -> None:
32
+ global tb_client # noqa: PLW0603
33
+ tb_client = self
34
+
35
+ @abstractmethod
36
+ def insert(self, data: ShpModel) -> bool:
37
+ """Insert (and probably replace) entry.
38
+
39
+ TODO: fixtures get replaced, but is that wanted for web?
40
+ """
41
+
42
+ @abstractmethod
43
+ def query_ids(self, model_type: str) -> List[int]:
44
+ pass
45
+
46
+ @abstractmethod
47
+ def query_names(self, model_type: str) -> List[str]:
48
+ pass
49
+
50
+ @abstractmethod
51
+ def query_item(
52
+ self, model_type: str, uid: Optional[int] = None, name: Optional[str] = None
53
+ ) -> dict:
54
+ pass
55
+
56
+ @abstractmethod
57
+ def try_inheritance(self, model_type: str, values: dict) -> (dict, list):
58
+ # TODO: maybe internal? yes
59
+ pass
60
+
61
+ def try_completing_model(self, model_type: str, values: dict) -> (dict, list):
62
+ """Init by name/id, for none existing instances raise Exception.
63
+
64
+ This is the main entry-point for querying a model (used be the core-lib).
65
+ """
66
+ if len(values) == 1 and next(iter(values.keys())) in {"id", "name"}:
67
+ try:
68
+ values = self.query_item(model_type, name=values.get("name"), uid=values.get("id"))
69
+ except ValueError as err:
70
+ raise ValueError(
71
+ "Query %s by name / ID failed - %s is unknown!", model_type, values
72
+ ) from err
73
+ return self.try_inheritance(model_type, values)
74
+
75
+ @abstractmethod
76
+ def fill_in_user_data(self, values: dict) -> dict:
77
+ # TODO: is it really helpful and needed?
78
+ pass
79
+
80
+
81
+ class FixturesClient(AbcClient):
82
+ """Client-Class to access the file based fixtures."""
83
+
84
+ def __init__(self) -> None:
85
+ super().__init__()
86
+ self._fixtures: Optional[Fixtures] = Fixtures()
87
+
88
+ def insert(self, data: ShpModel) -> bool:
89
+ wrap = Wrapper(
90
+ datatype=type(data).__name__,
91
+ parameters=data.model_dump(),
92
+ )
93
+ self._fixtures.insert_model(wrap)
94
+ return True
95
+
96
+ def query_ids(self, model_type: str) -> List[int]:
97
+ return list(self._fixtures[model_type].elements_by_id.keys())
98
+
99
+ def query_names(self, model_type: str) -> List[str]:
100
+ return list(self._fixtures[model_type].elements_by_name.keys())
101
+
102
+ def query_item(
103
+ self, model_type: str, uid: Optional[int] = None, name: Optional[str] = None
104
+ ) -> dict:
105
+ if uid is not None:
106
+ return self._fixtures[model_type].query_id(uid)
107
+ if name is not None:
108
+ return self._fixtures[model_type].query_name(name)
109
+ raise ValueError("Query needs either uid or name of object")
110
+
111
+ def try_inheritance(self, model_type: str, values: dict) -> (dict, list):
112
+ return self._fixtures[model_type].inheritance(values)
113
+
114
+ def fill_in_user_data(self, values: dict) -> dict:
115
+ """Add fake user-data when offline-client is used.
116
+
117
+ Hotfix until WebClient is working.
118
+ """
119
+ if values.get("owner") is None:
120
+ values["owner"] = "unknown"
121
+ if values.get("group") is None:
122
+ values["group"] = "unknown"
123
+ return values
124
+
125
+
126
+ tb_client: AbcClient = FixturesClient()