shepherd-core 2024.8.1__tar.gz → 2024.8.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 (146) hide show
  1. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/PKG-INFO +1 -1
  2. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/eenv_generator.py +1 -1
  3. shepherd_core-2024.8.2/examples/simulate_vharvester.py +74 -0
  4. shepherd_core-2024.8.2/examples/simulate_vsource.py +55 -0
  5. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/virtual_source_fixture.yaml +1 -1
  6. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/version.py +1 -1
  7. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/vsource/__init__.py +10 -0
  8. shepherd_core-2024.8.2/shepherd_core/vsource/target_model.py +62 -0
  9. shepherd_core-2024.8.2/shepherd_core/vsource/virtual_harvester_simulation.py +71 -0
  10. shepherd_core-2024.8.2/shepherd_core/vsource/virtual_source_simulation.py +78 -0
  11. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core.egg-info/PKG-INFO +1 -1
  12. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core.egg-info/SOURCES.txt +6 -3
  13. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/test_examples.py +3 -2
  14. shepherd_core-2024.8.1/examples/vharvester_simulation.py +0 -96
  15. shepherd_core-2024.8.1/examples/vsource_emulation.py +0 -86
  16. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/README.md +0 -0
  17. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/experiment_from_yaml.yaml +0 -0
  18. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/experiment_generic_var1.py +0 -0
  19. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/experiment_generic_var2.py +0 -0
  20. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/experiment_models.py +0 -0
  21. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/firmware_model.py +0 -0
  22. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/firmware_modification.py +0 -0
  23. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/inventory.py +0 -0
  24. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/uart_decode_waveform.py +0 -0
  25. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/examples/uart_raw2.csv +0 -0
  26. /shepherd_core-2024.8.1/examples/vsource_simulation.py → /shepherd_core-2024.8.2/examples/vsource_debug_sim.py +0 -0
  27. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/pyproject.toml +0 -0
  28. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/setup.cfg +0 -0
  29. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/__init__.py +0 -0
  30. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/calibration_hw_def.py +0 -0
  31. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/commons.py +0 -0
  32. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/__init__.py +0 -0
  33. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/base/__init__.py +0 -0
  34. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/base/cal_measurement.py +0 -0
  35. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/base/calibration.py +0 -0
  36. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/base/content.py +0 -0
  37. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/base/shepherd.py +0 -0
  38. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/base/timezone.py +0 -0
  39. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/base/wrapper.py +0 -0
  40. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/__init__.py +0 -0
  41. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/_external_fixtures.yaml +0 -0
  42. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/energy_environment.py +0 -0
  43. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -0
  44. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/firmware.py +0 -0
  45. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/firmware_datatype.py +0 -0
  46. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/virtual_harvester.py +0 -0
  47. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/virtual_harvester_fixture.yaml +0 -0
  48. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/content/virtual_source.py +0 -0
  49. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/experiment/__init__.py +0 -0
  50. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/experiment/experiment.py +0 -0
  51. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/experiment/observer_features.py +0 -0
  52. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/experiment/target_config.py +0 -0
  53. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/readme.md +0 -0
  54. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/task/__init__.py +0 -0
  55. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/task/emulation.py +0 -0
  56. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/task/firmware_mod.py +0 -0
  57. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/task/harvest.py +0 -0
  58. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/task/observer_tasks.py +0 -0
  59. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/task/programming.py +0 -0
  60. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/task/testbed_tasks.py +0 -0
  61. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/__init__.py +0 -0
  62. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/cape.py +0 -0
  63. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/cape_fixture.yaml +0 -0
  64. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/gpio.py +0 -0
  65. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -0
  66. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/mcu.py +0 -0
  67. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/mcu_fixture.yaml +0 -0
  68. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/observer.py +0 -0
  69. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/observer_fixture.yaml +0 -0
  70. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/target.py +0 -0
  71. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/target_fixture.yaml +0 -0
  72. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/testbed.py +0 -0
  73. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/testbed/testbed_fixture.yaml +0 -0
  74. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/data_models/virtual_source_doc.txt +0 -0
  75. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/decoder_waveform/__init__.py +0 -0
  76. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/decoder_waveform/uart.py +0 -0
  77. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/fw_tools/__init__.py +0 -0
  78. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/fw_tools/converter.py +0 -0
  79. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/fw_tools/converter_elf.py +0 -0
  80. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/fw_tools/patcher.py +0 -0
  81. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/fw_tools/validation.py +0 -0
  82. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/inventory/__init__.py +0 -0
  83. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/inventory/python.py +0 -0
  84. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/inventory/system.py +0 -0
  85. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/inventory/target.py +0 -0
  86. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/logger.py +0 -0
  87. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/reader.py +0 -0
  88. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/testbed_client/__init__.py +0 -0
  89. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/testbed_client/cache_path.py +0 -0
  90. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/testbed_client/client_abc_fix.py +0 -0
  91. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/testbed_client/client_web.py +0 -0
  92. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/testbed_client/fixtures.py +0 -0
  93. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/testbed_client/user_model.py +0 -0
  94. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/vsource/virtual_converter_model.py +0 -0
  95. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/vsource/virtual_harvester_model.py +0 -0
  96. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/vsource/virtual_source_model.py +0 -0
  97. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core/writer.py +0 -0
  98. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core.egg-info/dependency_links.txt +0 -0
  99. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core.egg-info/requires.txt +0 -0
  100. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core.egg-info/top_level.txt +0 -0
  101. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/shepherd_core.egg-info/zip-safe +0 -0
  102. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/__init__.py +0 -0
  103. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/conftest.py +0 -0
  104. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/__init__.py +0 -0
  105. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/conftest.py +0 -0
  106. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_cal_data.yaml +0 -0
  107. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_cal_data_faulty.yaml +0 -0
  108. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_cal_meas.yaml +0 -0
  109. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_cal_meas_faulty1.yaml +0 -0
  110. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_cal_meas_faulty2.yaml +0 -0
  111. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_config_emulator.yaml +0 -0
  112. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_config_experiment.yaml +0 -0
  113. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_config_experiment_alternative.yaml +0 -0
  114. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_config_harvester.yaml +0 -0
  115. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_config_testbed.yaml +0 -0
  116. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/example_config_virtsource.yaml +0 -0
  117. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_base_models.py +0 -0
  118. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_content_fixtures.py +0 -0
  119. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_content_models.py +0 -0
  120. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_examples.py +0 -0
  121. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_experiment_models.py +0 -0
  122. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_task_generation.py +0 -0
  123. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_task_models.py +0 -0
  124. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_testbed_fixtures.py +0 -0
  125. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/data_models/test_testbed_models.py +0 -0
  126. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/decoder_waveform/__init__.py +0 -0
  127. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/decoder_waveform/test_decoder.py +0 -0
  128. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/fw_tools/__init__.py +0 -0
  129. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/fw_tools/build_msp.elf +0 -0
  130. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/fw_tools/build_nrf.elf +0 -0
  131. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/fw_tools/conftest.py +0 -0
  132. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/fw_tools/test_converter.py +0 -0
  133. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/fw_tools/test_patcher.py +0 -0
  134. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/fw_tools/test_validation.py +0 -0
  135. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/inventory/__init__.py +0 -0
  136. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/inventory/test_inventory.py +0 -0
  137. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/test_cal_hw.py +0 -0
  138. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/test_logger.py +0 -0
  139. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/test_reader.py +0 -0
  140. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/test_writer.py +0 -0
  141. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/testbed_client/__init__.py +0 -0
  142. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/vsource/__init__.py +0 -0
  143. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/vsource/conftest.py +0 -0
  144. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/vsource/test_converter.py +0 -0
  145. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/tests/vsource/test_harvester.py +0 -0
  146. {shepherd_core-2024.8.1 → shepherd_core-2024.8.2}/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.8.1
3
+ Version: 2024.8.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>
@@ -35,7 +35,7 @@ for _v, _c in product(voltages_V, currents_A):
35
35
  voltage_vector = np.linspace(_v, _v, int(file.samplerate_sps * duration_s))
36
36
  current_vector = np.linspace(_c, _c, int(file.samplerate_sps * duration_s))
37
37
 
38
- for idx in trange(repetitions, desc="generate"):
38
+ for idx in trange(repetitions, desc="generate", leave=False):
39
39
  timestamps = idx * duration_s + timestamp_vector
40
40
  file.append_iv_data_si(timestamps, voltage_vector, current_vector)
41
41
 
@@ -0,0 +1,74 @@
1
+ """Demonstrate behavior of Virtual Harvester Algorithms.
2
+
3
+ - simulation is based on ivsamples derived from a solar-isc-voc-recording during a jogging-trip
4
+ - harvesting is done by various algorithms and preconfigured virtual harvesters
5
+ - results are printed on console (harvested energy)
6
+
7
+ Output:
8
+ E_out = 0.000 mWs -> cv20
9
+ E_out = 17.165 mWs -> cv10
10
+ E_out = 17.427 mWs -> mppt_voc
11
+ E_out = 17.242 mWs -> mppt_bq_solar
12
+ E_out = 13.998 mWs -> mppt_bq_thermoelectric
13
+ E_out = 15.202 mWs -> mppt_po
14
+ E_out = 17.811 mWs -> mppt_opt
15
+ """
16
+
17
+ from pathlib import Path
18
+
19
+ from shepherd_core import Reader
20
+ from shepherd_core.data_models import VirtualHarvesterConfig
21
+ from shepherd_core.vsource import simulate_harvester
22
+ from shepherd_data import ivonne
23
+
24
+ # config simulation
25
+ sim_duration = 32
26
+ file_ivonne = Path(__file__).parent.parent.parent / "shepherd_data/examples/jogging_10m.iv"
27
+ file_ivcurve = Path(__file__).parent / "jogging_ivcurve.h5"
28
+
29
+ hrv_list = [
30
+ "cv20",
31
+ # ⤷ fails due to lower solar voltage
32
+ "cv10",
33
+ "mppt_voc",
34
+ "mppt_bq_solar",
35
+ # ⤷ bq needs 16 s to start -> bad performance for this demo
36
+ "mppt_bq_thermoelectric",
37
+ # ⤷ thermoelectric setpoint -> bad performance for solar
38
+ "mppt_po",
39
+ "mppt_opt",
40
+ ]
41
+
42
+ save_files: bool = False
43
+
44
+ # convert IVonne to IVCurve
45
+ if not file_ivcurve.exists():
46
+ with ivonne.Reader(file_ivonne) as db:
47
+ db.convert_2_ivcurves(file_ivcurve, duration_s=sim_duration)
48
+
49
+ # Input Statistics
50
+ with Reader(file_ivcurve, verbose=False) as file:
51
+ window_size = file.get_window_samples()
52
+ I_in_max = 0.0
53
+ for _t, _v, _i in file.read_buffers():
54
+ I_in_max = max(I_in_max, _i.max())
55
+ print(
56
+ f"Input-file: \n"
57
+ f"\tE_in = {file.energy() * 1e3:.3f} mWs (not representative)\n"
58
+ f"\tI_in_max = {I_in_max * 1e3:.3f} mA\n"
59
+ f"\twindow_size = {window_size} n\n",
60
+ )
61
+
62
+ # Simulation
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
+ )
69
+ E_out_Ws = simulate_harvester(
70
+ config=VirtualHarvesterConfig(name=hrv_name),
71
+ path_input=file_ivcurve,
72
+ path_output=file_output,
73
+ )
74
+ print(f"E_out = {E_out_Ws * 1e3:.3f} mWs -> {hrv_name}")
@@ -0,0 +1,55 @@
1
+ """Demonstrate behavior of Virtual Source Algorithms.
2
+
3
+ The emulation recreates an observer-cape, the virtual Source and a virtual target
4
+ - input = hdf5-file with a harvest-recording
5
+ - output = hdf5-file
6
+ - config is currently hardcoded, but it could be an emulation-task
7
+ - target is currently a simple resistor
8
+
9
+ The output file can be analyzed and plotted with shepherds tool suite.
10
+
11
+ Output:
12
+ E_out = 0.007 mWs -> direct
13
+ E_out = 0.033 mWs -> diode+capacitor
14
+ E_out = 0.033 mWs -> diode+resistor+capacitor
15
+ E_out = 14.964 mWs -> BQ25504
16
+ E_out = 15.042 mWs -> BQ25504s
17
+ E_out = 13.909 mWs -> BQ25570
18
+ E_out = 14.073 mWs -> BQ25570s
19
+ """
20
+
21
+ from pathlib import Path
22
+
23
+ from shepherd_core.data_models import VirtualSourceConfig
24
+ from shepherd_core.vsource import ConstantCurrentTarget
25
+ from shepherd_core.vsource import simulate_source
26
+
27
+ # config simulation
28
+ file_input = Path(__file__).parent / "jogging_ivcurve.h5"
29
+
30
+ src_list = [
31
+ "direct",
32
+ "diode+capacitor",
33
+ "diode+resistor+capacitor",
34
+ "BQ25504",
35
+ "BQ25504s",
36
+ "BQ25570",
37
+ "BQ25570s",
38
+ ]
39
+ tgt = ConstantCurrentTarget(i_active_A=1e-3, i_sleep_A=200e-9)
40
+ save_files = False
41
+
42
+ for src_name in src_list:
43
+ file_output = (
44
+ file_input.with_name(file_input.stem + "_emu_" + src_name + file_input.suffix)
45
+ if save_files
46
+ else None
47
+ )
48
+
49
+ e_out_Ws = simulate_source(
50
+ config=VirtualSourceConfig(name=src_name),
51
+ target=tgt,
52
+ path_input=file_input,
53
+ path_output=file_output,
54
+ )
55
+ print(f"E_out = {e_out_Ws * 1e3:.3f} mWs -> {src_name}")
@@ -15,7 +15,7 @@
15
15
  interval_startup_delay_drain_ms: 0
16
16
 
17
17
  harvester:
18
- name: mppt_opt # harvester only active if input is "ivcurves"
18
+ name: mppt_opt # harvester only active if input is "ivcurve"
19
19
 
20
20
  V_input_max_mV: 10000
21
21
  I_input_max_mA: 4200
@@ -1,3 +1,3 @@
1
1
  """Separated string avoids circular imports."""
2
2
 
3
- version: str = "2024.8.1"
3
+ version: str = "2024.8.2"
@@ -1,13 +1,23 @@
1
1
  """Simulation model of the virtual source."""
2
2
 
3
+ from .target_model import ConstantCurrentTarget
4
+ from .target_model import ConstantPowerTarget
5
+ from .target_model import ResistiveTarget
3
6
  from .virtual_converter_model import PruCalibration
4
7
  from .virtual_converter_model import VirtualConverterModel
5
8
  from .virtual_harvester_model import VirtualHarvesterModel
9
+ from .virtual_harvester_simulation import simulate_harvester
6
10
  from .virtual_source_model import VirtualSourceModel
11
+ from .virtual_source_simulation import simulate_source
7
12
 
8
13
  __all__ = [
9
14
  "PruCalibration",
10
15
  "VirtualConverterModel",
11
16
  "VirtualHarvesterModel",
12
17
  "VirtualSourceModel",
18
+ "simulate_harvester",
19
+ "simulate_source",
20
+ "ResistiveTarget",
21
+ "ConstantCurrentTarget",
22
+ "ConstantPowerTarget",
13
23
  ]
@@ -0,0 +1,62 @@
1
+ """Virtual targets with different characteristics.
2
+
3
+ TODO: add more targets
4
+ - diode
5
+ - constant power
6
+ - constant current
7
+ - msp430 (const I)
8
+ - nRF (constant power due to regulator)
9
+ - riotee
10
+ """
11
+
12
+ from abc import ABC
13
+ from abc import abstractmethod
14
+
15
+
16
+ class TargetABC(ABC):
17
+ """Abstract base class for all targets."""
18
+
19
+ @abstractmethod
20
+ def step(self, voltage_uV: int, *, pwr_good: bool) -> float:
21
+ """Calculate one time step and return drawn current in nA."""
22
+
23
+
24
+ class ResistiveTarget(TargetABC):
25
+ """Predictable target for matching the real world."""
26
+
27
+ def __init__(self, resistance_Ohm: float, *, controlled: bool = False) -> None:
28
+ if resistance_Ohm <= 1e-3:
29
+ raise ValueError("Resistance must be greater than 1 mOhm.")
30
+ self.r_kOhm = 1e-3 * resistance_Ohm
31
+ self.ctrl = controlled
32
+
33
+ def step(self, voltage_uV: int, *, pwr_good: bool) -> float:
34
+ if pwr_good or not self.ctrl:
35
+ return voltage_uV / self.r_kOhm # = nA
36
+ return 0
37
+
38
+
39
+ class ConstantCurrentTarget(TargetABC):
40
+ """Recreate simple MCU without integrated regulator."""
41
+
42
+ def __init__(self, i_active_A: float, i_sleep_A: float = 0) -> None:
43
+ if i_active_A <= 0 or i_sleep_A <= 0:
44
+ raise ValueError("Current must be greater than 0.")
45
+ self.i_active_nA = 1e9 * i_active_A
46
+ self.i_sleep_nA = 1e9 * i_sleep_A
47
+
48
+ def step(self, voltage_uV: int, *, pwr_good: bool) -> float: # noqa: ARG002
49
+ return self.i_active_nA if pwr_good else self.i_sleep_nA
50
+
51
+
52
+ class ConstantPowerTarget(TargetABC):
53
+ """Recreate MCU with integrated regulator."""
54
+
55
+ def __init__(self, p_active_W: float, p_sleep_W: float = 0) -> None:
56
+ if p_active_W <= 0 or p_sleep_W <= 0:
57
+ raise ValueError("Power must be greater than 0.")
58
+ self.p_active_fW = 1e15 * p_active_W
59
+ self.p_sleep_fW = 1e15 * p_sleep_W
60
+
61
+ def step(self, voltage_uV: int, *, pwr_good: bool) -> float:
62
+ return (self.p_active_fW if pwr_good else self.p_sleep_fW) / voltage_uV # = nA
@@ -0,0 +1,71 @@
1
+ """Simulate behavior of virtual harvester algorithms.
2
+
3
+ The simulation recreates an observer-cape and the virtual harvester
4
+ - input = hdf5-file with an ivcurve
5
+ - output = optional as hdf5-file
6
+
7
+ The output file can be analyzed and plotted with shepherds tool suite.
8
+ """
9
+
10
+ from contextlib import ExitStack
11
+ from pathlib import Path
12
+ from typing import Optional
13
+
14
+ from tqdm import tqdm
15
+
16
+ from .. import CalibrationHarvester
17
+ from .. import Reader
18
+ from .. import Writer
19
+ from ..data_models.content.virtual_harvester import HarvesterPRUConfig
20
+ from ..data_models.content.virtual_harvester import VirtualHarvesterConfig
21
+ from .virtual_harvester_model import VirtualHarvesterModel
22
+
23
+
24
+ def simulate_harvester(
25
+ config: VirtualHarvesterConfig, path_input: Path, path_output: Optional[Path] = None
26
+ ) -> float:
27
+ """Simulate behavior of virtual harvester algorithms.
28
+
29
+ Fn return the harvested energy.
30
+ """
31
+ stack = ExitStack()
32
+ file_inp = Reader(path_input, verbose=False)
33
+ stack.enter_context(file_inp)
34
+ cal_inp = file_inp.get_calibration_data()
35
+
36
+ if path_output:
37
+ cal_hrv = CalibrationHarvester()
38
+ file_out = Writer(
39
+ path_output, cal_data=cal_hrv, mode="harvester", verbose=False, force_overwrite=True
40
+ )
41
+ stack.enter_context(file_out)
42
+ cal_out = file_out.get_calibration_data()
43
+ file_out.store_hostname("hrv_sim_" + config.name)
44
+
45
+ hrv_pru = HarvesterPRUConfig.from_vhrv(
46
+ config,
47
+ for_emu=True,
48
+ dtype_in=file_inp.get_datatype(),
49
+ window_size=file_inp.get_window_samples(),
50
+ )
51
+ hrv = VirtualHarvesterModel(hrv_pru)
52
+ e_out_Ws = 0.0
53
+
54
+ for _t, v_inp, i_inp in tqdm(
55
+ file_inp.read_buffers(is_raw=True), total=file_inp.buffers_n, desc="Buffers", leave=False
56
+ ):
57
+ v_uV = cal_inp.voltage.raw_to_si(v_inp) * 1e6
58
+ i_nA = cal_inp.current.raw_to_si(i_inp) * 1e9
59
+ length = min(v_uV.size, i_nA.size)
60
+ for _n in range(length):
61
+ v_uV[_n], i_nA[_n] = hrv.ivcurve_sample(
62
+ _voltage_uV=int(v_uV[_n]), _current_nA=int(i_nA[_n])
63
+ )
64
+ e_out_Ws += (v_uV * i_nA).sum() * 1e-15 * file_inp.sample_interval_s
65
+ if path_output:
66
+ v_out = cal_out.voltage.si_to_raw(v_uV / 1e6)
67
+ i_out = cal_out.current.si_to_raw(i_nA / 1e9)
68
+ file_out.append_iv_data_raw(_t, v_out, i_out)
69
+
70
+ stack.close()
71
+ return e_out_Ws
@@ -0,0 +1,78 @@
1
+ """Simulate behavior of virtual source algorithms.
2
+
3
+ The simulation recreates an observer-cape, the virtual Source and a virtual target
4
+ - input = hdf5-file with a harvest-recording
5
+ - output = optional as hdf5-file
6
+
7
+ The output file can be analyzed and plotted with shepherds tool suite.
8
+ """
9
+
10
+ from contextlib import ExitStack
11
+ from pathlib import Path
12
+ from typing import Optional
13
+
14
+ from tqdm import tqdm
15
+
16
+ from .. import CalibrationEmulator
17
+ from .. import Reader
18
+ from .. import Writer
19
+ from ..data_models import VirtualSourceConfig
20
+ from . import VirtualSourceModel
21
+ from .target_model import TargetABC
22
+
23
+
24
+ def simulate_source(
25
+ config: VirtualSourceConfig,
26
+ target: TargetABC,
27
+ path_input: Path,
28
+ path_output: Optional[Path] = None,
29
+ ) -> float:
30
+ """Simulate behavior of virtual source algorithms.
31
+
32
+ FN returns the consumed energy of the target.
33
+ """
34
+ stack = ExitStack()
35
+ file_inp = Reader(path_input, verbose=False)
36
+ stack.enter_context(file_inp)
37
+ cal_emu = CalibrationEmulator()
38
+ cal_inp = file_inp.get_calibration_data()
39
+
40
+ if path_output:
41
+ file_out = Writer(
42
+ path_output, cal_data=cal_emu, mode="emulator", verbose=False, force_overwrite=True
43
+ )
44
+ stack.enter_context(file_out)
45
+ file_out.store_hostname("emu_sim_" + config.name)
46
+ file_out.store_config(config.model_dump())
47
+ cal_out = file_out.get_calibration_data()
48
+
49
+ src = VirtualSourceModel(
50
+ config, cal_emu, log_intermediate=False, window_size=file_inp.get_window_samples()
51
+ )
52
+ i_out_nA = 0
53
+ e_out_Ws = 0.0
54
+
55
+ for _t, v_inp, i_inp in tqdm(
56
+ file_inp.read_buffers(is_raw=True), total=file_inp.buffers_n, desc="Buffers", leave=False
57
+ ):
58
+ v_uV = 1e6 * cal_inp.voltage.raw_to_si(v_inp)
59
+ i_nA = 1e9 * cal_inp.current.raw_to_si(i_inp)
60
+
61
+ for _n in range(len(_t)):
62
+ v_uV[_n] = src.iterate_sampling(
63
+ V_inp_uV=int(v_uV[_n]),
64
+ I_inp_nA=int(i_nA[_n]),
65
+ I_out_nA=i_out_nA,
66
+ )
67
+ i_out_nA = target.step(int(v_uV[_n]), pwr_good=src.cnv.get_power_good())
68
+ i_nA[_n] = i_out_nA
69
+ # TODO: src.cnv.get_I_mod_out_nA() has more internal drains
70
+
71
+ e_out_Ws += (v_uV * i_nA).sum() * 1e-15 * file_inp.sample_interval_s
72
+ if path_output:
73
+ v_out = cal_out.voltage.si_to_raw(1e-6 * v_uV)
74
+ i_out = cal_out.current.si_to_raw(1e-9 * i_nA)
75
+ file_out.append_iv_data_raw(_t, v_out, i_out)
76
+
77
+ stack.close()
78
+ return e_out_Ws
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: shepherd_core
3
- Version: 2024.8.1
3
+ Version: 2024.8.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>
@@ -8,11 +8,11 @@ examples/experiment_models.py
8
8
  examples/firmware_model.py
9
9
  examples/firmware_modification.py
10
10
  examples/inventory.py
11
+ examples/simulate_vharvester.py
12
+ examples/simulate_vsource.py
11
13
  examples/uart_decode_waveform.py
12
14
  examples/uart_raw2.csv
13
- examples/vharvester_simulation.py
14
- examples/vsource_emulation.py
15
- examples/vsource_simulation.py
15
+ examples/vsource_debug_sim.py
16
16
  shepherd_core/__init__.py
17
17
  shepherd_core/calibration_hw_def.py
18
18
  shepherd_core/commons.py
@@ -88,9 +88,12 @@ shepherd_core/testbed_client/client_web.py
88
88
  shepherd_core/testbed_client/fixtures.py
89
89
  shepherd_core/testbed_client/user_model.py
90
90
  shepherd_core/vsource/__init__.py
91
+ shepherd_core/vsource/target_model.py
91
92
  shepherd_core/vsource/virtual_converter_model.py
92
93
  shepherd_core/vsource/virtual_harvester_model.py
94
+ shepherd_core/vsource/virtual_harvester_simulation.py
93
95
  shepherd_core/vsource/virtual_source_model.py
96
+ shepherd_core/vsource/virtual_source_simulation.py
94
97
  tests/__init__.py
95
98
  tests/conftest.py
96
99
  tests/test_cal_hw.py
@@ -18,8 +18,9 @@ examples = [
18
18
  "experiment_models.py",
19
19
  "inventory.py",
20
20
  "uart_decode_waveform.py",
21
- "vharvester_simulation.py",
22
- "vsource_simulation.py",
21
+ "simulate_vharvester.py",
22
+ "simulate_vsource.py",
23
+ "vsource_debug_sim.py",
23
24
  ]
24
25
 
25
26
 
@@ -1,96 +0,0 @@
1
- """Demonstrate behavior of Virtual Harvester Algorithms.
2
-
3
- - simulation is based on ivsamples derived from a solar-isc-voc-recording during a jogging-trip
4
- - harvesting is done by various algorithms and preconfigured virtual harvesters
5
- - results are printed on console (harvested energy)
6
-
7
- """
8
-
9
- from contextlib import ExitStack
10
- from pathlib import Path
11
-
12
- from shepherd_core import CalibrationHarvester
13
- from shepherd_core import Reader
14
- from shepherd_core import Writer
15
- from shepherd_core.data_models import VirtualHarvesterConfig
16
- from shepherd_core.data_models.content.virtual_harvester import HarvesterPRUConfig
17
- from shepherd_core.vsource import VirtualHarvesterModel
18
- from shepherd_data import ivonne
19
-
20
- # config simulation
21
- sim_duration = 32
22
- file_ivonne = Path(__file__).parent.parent.parent / "shepherd_data/examples/jogging_10m.iv"
23
- file_ivcurve = Path(__file__).parent / "jogging_ivcurve.h5"
24
-
25
- hrv_list = [
26
- "cv20",
27
- # ⤷ fails due to lower solar voltage
28
- "cv10",
29
- "mppt_voc",
30
- "mppt_bq_solar",
31
- # ⤷ bq needs 16 s to start -> bad performance for this demo
32
- "mppt_bq_thermoelectric",
33
- # ⤷ thermoelectric setpoint -> bad performance for solar
34
- "mppt_po",
35
- "mppt_opt",
36
- ]
37
-
38
- save_files: bool = True
39
-
40
- # convert IVonne to IVCurve
41
- if not file_ivcurve.exists():
42
- with ivonne.Reader(file_ivonne) as db:
43
- db.convert_2_ivcurves(file_ivcurve, duration_s=sim_duration)
44
-
45
- # Input Statistics
46
- with Reader(file_ivcurve, verbose=False) as file:
47
- window_size = file.get_window_samples()
48
- I_in_max = 0.0
49
- for _t, _v, _i in file.read_buffers():
50
- I_in_max = max(I_in_max, _i.max())
51
- print(
52
- f"Input-file: \n"
53
- f"\tE_in = {file.energy() * 1e3:.3f} mWs (not representative)\n"
54
- f"\tI_in_max = {I_in_max * 1e3:.3f} mA\n"
55
- f"\twindow_size = {window_size} n\n",
56
- )
57
-
58
- # Simulation
59
- for hrv_name in hrv_list:
60
- E_out_Ws = 0.0
61
- _cal = CalibrationHarvester()
62
- if save_files:
63
- stack = ExitStack()
64
- file_output = file_ivcurve.with_name(
65
- file_ivcurve.stem + "_" + hrv_name + file_ivcurve.suffix
66
- )
67
- fh_output = Writer(
68
- file_output, cal_data=_cal, mode="harvester", verbose=False, force_overwrite=True
69
- )
70
- stack.enter_context(fh_output)
71
- fh_output.store_hostname("hrv_sim_" + hrv_name)
72
-
73
- with Reader(file_ivcurve, verbose=False) as file:
74
- hrv_config = VirtualHarvesterConfig(name=hrv_name)
75
- hrv_pru = HarvesterPRUConfig.from_vhrv(
76
- hrv_config,
77
- for_emu=True,
78
- dtype_in=file.get_datatype(),
79
- window_size=4 * file.get_window_samples(),
80
- )
81
- hrv = VirtualHarvesterModel(hrv_pru)
82
- for _t, _v, _i in file.read_buffers():
83
- # TODO: _t should be handed to new file without conversions
84
- length = max(_v.size, _i.size)
85
- for _n in range(length):
86
- _v[_n], _i[_n] = hrv.ivcurve_sample(
87
- _voltage_uV=_v[_n] * 10**6, _current_nA=_i[_n] * 10**9
88
- )
89
- E_out_Ws += (_v * _i).sum() * 1e-15 * file.sample_interval_s
90
- if save_files:
91
- fh_output.append_iv_data_si(_t, _v / 1e6, _i / 1e9)
92
- if save_files:
93
- stack.close()
94
- with Reader(file_output) as fh_output:
95
- fh_output.save_metadata()
96
- print(f"E_out = {E_out_Ws * 1e3:.3f} mWs -> {hrv_name}")
@@ -1,86 +0,0 @@
1
- """Demonstrate behavior of Virtual Source Algorithms.
2
-
3
- The emulation recreates an observer-cape, the virtual Source and a virtual target
4
- - input = hdf5-file with a harvest-recording
5
- - output = hdf5-file
6
- - config is currently hardcoded, but it could be an emulation-task
7
- - target is currently a simple resistor
8
-
9
- The output file can be analyzed and plotted with shepherds tool suite.
10
- """
11
- # TODO: `shepherd-data emulate config.yaml`
12
-
13
- from pathlib import Path
14
-
15
- import numpy as np
16
- from tqdm import tqdm
17
-
18
- from shepherd_core import CalibrationEmulator
19
- from shepherd_core import Reader
20
- from shepherd_core import Writer
21
- from shepherd_core.data_models import VirtualHarvesterConfig
22
- from shepherd_core.data_models import VirtualSourceConfig
23
- from shepherd_core.vsource import VirtualSourceModel
24
-
25
- # config simulation
26
- file_input = Path(__file__).parent / "jogging_ivcurve.h5"
27
-
28
- src_list = ["BQ25504"]
29
-
30
- I_mcu_sleep_A = 3e-3
31
- I_mcu_active_A = 3e-3
32
- R_Ohm = 1000
33
-
34
- for vs_name in src_list:
35
- file_output = file_input.with_name(file_input.stem + "_emu_" + vs_name + file_input.suffix)
36
-
37
- cal_emu = CalibrationEmulator()
38
- src_config = VirtualSourceConfig(
39
- inherit_from=vs_name,
40
- V_intermediate_init_mV=3000,
41
- harvester=VirtualHarvesterConfig(name="mppt_bq_solar"),
42
- C_intermediate_uF=50,
43
- )
44
-
45
- with Reader(file_input, verbose=False) as f_inp, Writer(
46
- file_output, cal_data=cal_emu, mode="emulator", verbose=False
47
- ) as f_out:
48
- window_size = f_inp.get_window_samples()
49
- f_out.store_hostname("emu_sim_" + vs_name)
50
- f_out.store_config(src_config.model_dump())
51
- src = VirtualSourceModel(
52
- src_config, cal_emu, log_intermediate=False, window_size=window_size
53
- )
54
-
55
- I_out_nA = 0
56
-
57
- for _t, _V_inp, _I_inp in tqdm(f_inp.read_buffers(), total=f_inp.buffers_n):
58
- V_out = np.empty(_V_inp.shape)
59
- I_out = np.empty(_I_inp.shape)
60
-
61
- for _iter in range(len(_t)):
62
- V_out_uV = src.iterate_sampling(
63
- V_inp_uV=_V_inp[_iter] * 10**6,
64
- I_inp_nA=_I_inp[_iter] * 10**9,
65
- I_out_nA=I_out_nA,
66
- )
67
- I_out_nA = 1e3 * V_out_uV / R_Ohm
68
-
69
- V_out[_iter] = V_out_uV / 1e6
70
- I_out[_iter] = I_out_nA / 1e9
71
-
72
- # TODO: src.cnv.get_I_mod_out_nA() has more internal drains
73
-
74
- f_out.append_iv_data_si(_t, V_out, I_out)
75
-
76
- # listen to power-good signal
77
- """
78
- if src.cnv.get_power_good():
79
- I_out_nA = int(I_mcu_active_A * 10 ** 9)
80
- N_good += 1
81
- else:
82
- I_out_nA = int(I_mcu_sleep_A * 10 ** 9)
83
- """
84
-
85
- with Reader(file_output, verbose=False) as f_out:
86
- f_out.save_metadata()