shepherd-core 2023.12.1__py3-none-any.whl → 2024.4.2__py3-none-any.whl

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 (116) hide show
  1. shepherd_core/__init__.py +5 -4
  2. shepherd_core/calibration_hw_def.py +9 -1
  3. shepherd_core/commons.py +2 -0
  4. shepherd_core/data_models/__init__.py +11 -0
  5. shepherd_core/data_models/base/__init__.py +4 -1
  6. shepherd_core/data_models/base/cal_measurement.py +18 -6
  7. shepherd_core/data_models/base/calibration.py +41 -16
  8. shepherd_core/data_models/base/content.py +20 -5
  9. shepherd_core/data_models/base/shepherd.py +23 -12
  10. shepherd_core/data_models/base/timezone.py +5 -0
  11. shepherd_core/data_models/base/wrapper.py +3 -3
  12. shepherd_core/data_models/content/__init__.py +5 -4
  13. shepherd_core/data_models/content/_external_fixtures.yaml +32 -16
  14. shepherd_core/data_models/content/energy_environment.py +7 -5
  15. shepherd_core/data_models/content/energy_environment_fixture.yaml +3 -0
  16. shepherd_core/data_models/content/firmware.py +12 -5
  17. shepherd_core/data_models/content/firmware_datatype.py +7 -0
  18. shepherd_core/data_models/content/virtual_harvester.py +25 -20
  19. shepherd_core/data_models/content/virtual_harvester_fixture.yaml +1 -0
  20. shepherd_core/data_models/content/virtual_source.py +40 -23
  21. shepherd_core/data_models/content/virtual_source_fixture.yaml +1 -0
  22. shepherd_core/data_models/experiment/__init__.py +5 -4
  23. shepherd_core/data_models/experiment/experiment.py +16 -15
  24. shepherd_core/data_models/experiment/observer_features.py +18 -12
  25. shepherd_core/data_models/experiment/target_config.py +11 -7
  26. shepherd_core/data_models/readme.md +88 -0
  27. shepherd_core/data_models/task/__init__.py +10 -3
  28. shepherd_core/data_models/task/emulation.py +9 -6
  29. shepherd_core/data_models/task/firmware_mod.py +4 -2
  30. shepherd_core/data_models/task/harvest.py +5 -4
  31. shepherd_core/data_models/task/observer_tasks.py +4 -2
  32. shepherd_core/data_models/task/programming.py +3 -1
  33. shepherd_core/data_models/task/testbed_tasks.py +10 -4
  34. shepherd_core/data_models/testbed/__init__.py +5 -2
  35. shepherd_core/data_models/testbed/cape.py +8 -6
  36. shepherd_core/data_models/testbed/gpio.py +11 -9
  37. shepherd_core/data_models/testbed/mcu.py +10 -10
  38. shepherd_core/data_models/testbed/observer.py +10 -5
  39. shepherd_core/data_models/testbed/observer_fixture.yaml +23 -22
  40. shepherd_core/data_models/testbed/target.py +5 -3
  41. shepherd_core/data_models/testbed/target_fixture.yaml +11 -11
  42. shepherd_core/data_models/testbed/testbed.py +6 -3
  43. shepherd_core/decoder_waveform/__init__.py +2 -0
  44. shepherd_core/decoder_waveform/uart.py +44 -25
  45. shepherd_core/fw_tools/__init__.py +2 -0
  46. shepherd_core/fw_tools/converter.py +20 -9
  47. shepherd_core/fw_tools/converter_elf.py +3 -0
  48. shepherd_core/fw_tools/patcher.py +16 -4
  49. shepherd_core/fw_tools/validation.py +25 -5
  50. shepherd_core/inventory/__init__.py +66 -6
  51. shepherd_core/inventory/python.py +4 -0
  52. shepherd_core/inventory/system.py +13 -1
  53. shepherd_core/inventory/target.py +4 -0
  54. shepherd_core/logger.py +5 -0
  55. shepherd_core/reader.py +44 -26
  56. shepherd_core/testbed_client/__init__.py +2 -0
  57. shepherd_core/testbed_client/cache_path.py +17 -0
  58. shepherd_core/testbed_client/client.py +14 -8
  59. shepherd_core/testbed_client/fixtures.py +30 -11
  60. shepherd_core/testbed_client/user_model.py +13 -6
  61. shepherd_core/vsource/__init__.py +2 -0
  62. shepherd_core/vsource/virtual_converter_model.py +11 -4
  63. shepherd_core/vsource/virtual_harvester_model.py +8 -1
  64. shepherd_core/vsource/virtual_source_model.py +10 -5
  65. shepherd_core/writer.py +28 -20
  66. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/METADATA +50 -34
  67. shepherd_core-2024.4.2.dist-info/RECORD +75 -0
  68. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/WHEEL +1 -1
  69. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/top_level.txt +0 -1
  70. shepherd_core-2023.12.1.dist-info/RECORD +0 -117
  71. tests/__init__.py +0 -0
  72. tests/conftest.py +0 -64
  73. tests/data_models/__init__.py +0 -0
  74. tests/data_models/conftest.py +0 -14
  75. tests/data_models/example_cal_data.yaml +0 -31
  76. tests/data_models/example_cal_data_faulty.yaml +0 -29
  77. tests/data_models/example_cal_meas.yaml +0 -178
  78. tests/data_models/example_cal_meas_faulty1.yaml +0 -142
  79. tests/data_models/example_cal_meas_faulty2.yaml +0 -136
  80. tests/data_models/example_config_emulator.yaml +0 -41
  81. tests/data_models/example_config_experiment.yaml +0 -16
  82. tests/data_models/example_config_experiment_alternative.yaml +0 -14
  83. tests/data_models/example_config_harvester.yaml +0 -15
  84. tests/data_models/example_config_testbed.yaml +0 -26
  85. tests/data_models/example_config_virtsource.yaml +0 -78
  86. tests/data_models/test_base_models.py +0 -205
  87. tests/data_models/test_content_fixtures.py +0 -41
  88. tests/data_models/test_content_models.py +0 -282
  89. tests/data_models/test_examples.py +0 -48
  90. tests/data_models/test_experiment_models.py +0 -277
  91. tests/data_models/test_task_generation.py +0 -52
  92. tests/data_models/test_task_models.py +0 -131
  93. tests/data_models/test_testbed_fixtures.py +0 -47
  94. tests/data_models/test_testbed_models.py +0 -187
  95. tests/decoder_waveform/__init__.py +0 -0
  96. tests/decoder_waveform/test_decoder.py +0 -34
  97. tests/fw_tools/__init__.py +0 -0
  98. tests/fw_tools/conftest.py +0 -5
  99. tests/fw_tools/test_converter.py +0 -76
  100. tests/fw_tools/test_patcher.py +0 -66
  101. tests/fw_tools/test_validation.py +0 -56
  102. tests/inventory/__init__.py +0 -0
  103. tests/inventory/test_inventory.py +0 -20
  104. tests/test_cal_hw.py +0 -34
  105. tests/test_examples.py +0 -40
  106. tests/test_logger.py +0 -15
  107. tests/test_reader.py +0 -283
  108. tests/test_writer.py +0 -169
  109. tests/testbed_client/__init__.py +0 -0
  110. tests/vsource/__init__.py +0 -0
  111. tests/vsource/conftest.py +0 -49
  112. tests/vsource/test_converter.py +0 -161
  113. tests/vsource/test_harvester.py +0 -73
  114. tests/vsource/test_z.py +0 -5
  115. /shepherd_core/data_models/{doc_virtual_source.py → virtual_source_doc.txt} +0 -0
  116. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/zip-safe +0 -0
@@ -1,161 +0,0 @@
1
- from pathlib import Path
2
- from typing import Optional
3
-
4
- import pytest
5
- from pytest import approx
6
-
7
- from shepherd_core import CalibrationEmulator
8
- from shepherd_core import Reader
9
- from shepherd_core.data_models import EnergyDType
10
- from shepherd_core.data_models import VirtualSourceConfig
11
- from shepherd_core.vsource import VirtualSourceModel
12
-
13
- # virtual_converter_model gets tested below with vsrc_model
14
-
15
- src_list = [
16
- "direct",
17
- "diode+capacitor",
18
- "diode+resistor+capacitor",
19
- "BQ25504",
20
- "BQ25504s",
21
- "BQ25570",
22
- "BQ25570s",
23
- ]
24
-
25
-
26
- def src_model(
27
- name: str,
28
- dtype_in: EnergyDType = EnergyDType.ivsample,
29
- window_size: Optional[int] = None,
30
- ) -> VirtualSourceModel:
31
- src_config = VirtualSourceConfig(name=name)
32
- cal_emu = CalibrationEmulator()
33
- return VirtualSourceModel(
34
- src_config,
35
- cal_emu,
36
- log_intermediate=False,
37
- dtype_in=dtype_in,
38
- window_size=window_size,
39
- )
40
-
41
-
42
- def c_leak_fWs(src: VirtualSourceModel, iterations: int) -> float:
43
- return iterations * src.cnv.V_mid_uV * src.cfg_src.I_intermediate_leak_nA
44
-
45
-
46
- @pytest.mark.parametrize("src_name", src_list)
47
- def test_vsource_vsrc_min(src_name: str) -> None:
48
- src = src_model(src_name)
49
- src.iterate_sampling()
50
-
51
-
52
- def test_vsource_vsrc_static1() -> None:
53
- iterations = 2_000
54
- src = src_model("BQ25504")
55
- for _ in range(iterations):
56
- src.iterate_sampling(V_inp_uV=3_000_000, I_inp_nA=0)
57
- assert src.W_inp_fWs == 0.0
58
- assert src.W_out_fWs == approx(c_leak_fWs(src, iterations), rel=1e-4, abs=1e-6)
59
-
60
-
61
- def test_vsource_vsrc_static2() -> None:
62
- iterations = 2_000
63
- src = src_model("BQ25504")
64
- for _ in range(iterations):
65
- src.iterate_sampling(V_inp_uV=0, I_inp_nA=3_000_000)
66
- assert src.W_inp_fWs == 0.0
67
- assert src.W_out_fWs == approx(c_leak_fWs(src, iterations), rel=1e-4, abs=1e-6)
68
-
69
-
70
- @pytest.mark.parametrize("src_name", src_list[2:])
71
- def test_vsource_charge(src_name: str) -> None:
72
- iterations = 4_000
73
- src = src_model(src_name)
74
- for v_mV in range(iterations):
75
- src.iterate_sampling(V_inp_uV=v_mV * 1000, I_inp_nA=1_000_000)
76
- v_out = src.iterate_sampling(V_inp_uV=1_000_000, I_inp_nA=1_000_000)
77
- assert src.W_inp_fWs > 0.0
78
- assert src.W_out_fWs == approx(c_leak_fWs(src, iterations), rel=0.12, abs=1e-3)
79
- assert v_out > 0.0
80
-
81
-
82
- @pytest.mark.parametrize("src_name", src_list[4:])
83
- def test_vsource_drain(src_name: str) -> None:
84
- iterations = 4_000
85
- src = src_model(src_name)
86
- for c_uA in range(iterations):
87
- src.iterate_sampling(I_out_nA=c_uA * 1000)
88
- v_out = src.iterate_sampling()
89
- assert src.W_inp_fWs == 0.0
90
- assert src.W_out_fWs > c_leak_fWs(src, iterations)
91
- assert v_out >= 0.0
92
-
93
-
94
- def test_vsource_vsrc_over_voltage() -> None:
95
- iterations = 100
96
- src = src_model("BQ25504")
97
- for _ in range(iterations):
98
- src.iterate_sampling(V_inp_uV=10 * 10**6, I_inp_nA=3_000_000)
99
- assert src.cnv.V_input_uV <= 5 * 10**6
100
- assert src.W_inp_fWs > 0.0
101
-
102
-
103
- def test_vsource_vsrc_over_current() -> None:
104
- iterations = 100
105
- src = src_model("BQ25504")
106
- for _ in range(iterations):
107
- src.iterate_sampling(V_inp_uV=5 * 10**6, I_inp_nA=100 * 10**6)
108
- assert src.W_inp_fWs > 0.0
109
-
110
-
111
- def test_vsource_vsrc_cycle() -> None:
112
- iterations = 2000
113
- src = src_model("BQ25504s")
114
-
115
- for _ in range(iterations):
116
- src.iterate_sampling(V_inp_uV=5 * 10**6, I_inp_nA=4 * 10**6)
117
- v_out = src.iterate_sampling()
118
- assert v_out > 0
119
-
120
- for _ in range(iterations):
121
- src.iterate_sampling(I_out_nA=40 * 10**6)
122
- v_out = src.iterate_sampling()
123
- assert v_out == 0
124
-
125
- for _ in range(iterations):
126
- src.iterate_sampling(V_inp_uV=5 * 10**6, I_inp_nA=4 * 10**6)
127
- v_out = src.iterate_sampling()
128
- assert v_out > 0
129
-
130
- assert src.W_out_fWs > 3 * c_leak_fWs(src, iterations)
131
- assert src.W_inp_fWs > src.W_out_fWs
132
-
133
-
134
- def test_vsource_vsrc_create_files(
135
- file_ivcurve: Path, file_ivsample: Path, file_isc_voc: Path
136
- ) -> None:
137
- pass
138
-
139
-
140
- @pytest.mark.parametrize("src_name", src_list)
141
- def test_vsource_vsrc_sim_curve(src_name: str, file_ivcurve: Path) -> None:
142
- with Reader(file_ivcurve) as file:
143
- window_size = file.get_window_samples()
144
- dtype = file.get_datatype()
145
- src = src_model("BQ25504s", dtype_in=dtype, window_size=window_size)
146
- for _t, _v, _i in file.read_buffers():
147
- length = max(_v.size, _i.size)
148
- for _n in range(length):
149
- src.iterate_sampling(V_inp_uV=_v[_n] * 10**6, I_inp_nA=_i[_n] * 10**9)
150
-
151
-
152
- @pytest.mark.parametrize("src_name", src_list)
153
- def test_vsource_vsrc_sim_sample(src_name: str, file_ivsample: Path) -> None:
154
- with Reader(file_ivsample) as file:
155
- window_size = file.get_window_samples()
156
- dtype = file.get_datatype()
157
- src = src_model("BQ25504s", dtype_in=dtype, window_size=window_size)
158
- for _t, _v, _i in file.read_buffers():
159
- length = max(_v.size, _i.size)
160
- for _n in range(length):
161
- src.iterate_sampling(V_inp_uV=_v[_n] * 10**6, I_inp_nA=_i[_n] * 10**9)
@@ -1,73 +0,0 @@
1
- from pathlib import Path
2
-
3
- import pytest
4
-
5
- from shepherd_core import Reader
6
- from shepherd_core.data_models import EnergyDType
7
- from shepherd_core.data_models import VirtualHarvesterConfig
8
- from shepherd_core.data_models.content.virtual_harvester import HarvesterPRUConfig
9
- from shepherd_core.vsource import VirtualHarvesterModel
10
-
11
- hrv_list = [
12
- "ivcurve",
13
- "iv1000",
14
- "isc_voc",
15
- "cv20",
16
- "mppt_voc",
17
- "mppt_bq",
18
- "mppt_bq_solar",
19
- "mppt_po",
20
- "mppt_opt",
21
- ]
22
-
23
-
24
- @pytest.mark.parametrize("hrv_name", hrv_list)
25
- def test_vsource_hrv_min(hrv_name: str) -> None:
26
- hrv_config = VirtualHarvesterConfig(name=hrv_name)
27
- hrv_pru = HarvesterPRUConfig.from_vhrv(hrv_config)
28
- _ = VirtualHarvesterModel(hrv_pru)
29
-
30
-
31
- def test_vsource_hrv_create_files(
32
- file_ivcurve: Path, file_ivsample: Path, file_isc_voc: Path
33
- ) -> None:
34
- pass
35
-
36
-
37
- @pytest.mark.parametrize("hrv_name", hrv_list[:3])
38
- def test_vsource_hrv_fail_ivcurve(hrv_name: str) -> None:
39
- # the first algos are not usable for ivcurve
40
- with pytest.raises(ValueError):
41
- hrv_config = VirtualHarvesterConfig(name=hrv_name)
42
- _ = HarvesterPRUConfig.from_vhrv(hrv_config, for_emu=True, dtype_in=EnergyDType.ivcurve)
43
-
44
-
45
- @pytest.mark.parametrize("hrv_name", hrv_list[3:])
46
- def test_vsource_hrv_sim(hrv_name: str, file_ivcurve: Path) -> None:
47
- with Reader(file_ivcurve) as file:
48
- hrv_config = VirtualHarvesterConfig(name=hrv_name)
49
- hrv_pru = HarvesterPRUConfig.from_vhrv(
50
- hrv_config,
51
- for_emu=True,
52
- dtype_in=file.get_datatype(),
53
- window_size=file.get_window_samples(),
54
- )
55
- hrv = VirtualHarvesterModel(hrv_pru)
56
- for _t, _v, _i in file.read_buffers():
57
- length = max(_v.size, _i.size)
58
- for _n in range(length):
59
- hrv.ivcurve_sample(_voltage_uV=_v[_n] * 10**6, _current_nA=_i[_n] * 10**9)
60
-
61
-
62
- @pytest.mark.parametrize("hrv_name", hrv_list[3:])
63
- def test_vsource_hrv_fail_isc_voc(hrv_name: str) -> None:
64
- # not implemented ATM
65
- with pytest.raises(ValueError):
66
- hrv_config = VirtualHarvesterConfig(name=hrv_name)
67
- _ = HarvesterPRUConfig.from_vhrv(hrv_config, for_emu=True, dtype_in=EnergyDType.isc_voc)
68
-
69
-
70
- def test_vsource_hrv_fail_unknown_type() -> None:
71
- with pytest.raises(KeyError):
72
- hrv_config = VirtualHarvesterConfig(name="mppt_voc")
73
- _ = HarvesterPRUConfig.from_vhrv(hrv_config, for_emu=True, dtype_in="xyz")
tests/vsource/test_z.py DELETED
@@ -1,5 +0,0 @@
1
- from pathlib import Path
2
-
3
-
4
- def test_vsource_cleanup(file_cleanup: Path) -> None:
5
- pass