shepherd-core 2024.7.3__tar.gz → 2024.8.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/PKG-INFO +9 -7
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/README.md +8 -6
- shepherd_core-2024.8.1/examples/eenv_generator.py +43 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/vharvester_simulation.py +26 -3
- shepherd_core-2024.8.1/examples/vsource_emulation.py +86 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/calibration_hw_def.py +15 -12
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/base/calibration.py +23 -24
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/virtual_harvester.py +18 -11
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/virtual_harvester_fixture.yaml +10 -13
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/virtual_source.py +6 -4
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/virtual_source_fixture.yaml +10 -8
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/reader.py +9 -4
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/version.py +1 -1
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/vsource/virtual_converter_model.py +21 -6
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/vsource/virtual_harvester_model.py +18 -8
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/writer.py +13 -3
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core.egg-info/PKG-INFO +9 -7
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core.egg-info/SOURCES.txt +2 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/vsource/test_converter.py +10 -4
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/experiment_from_yaml.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/experiment_generic_var1.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/experiment_generic_var2.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/experiment_models.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/firmware_model.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/firmware_modification.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/inventory.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/uart_decode_waveform.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/uart_raw2.csv +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/examples/vsource_simulation.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/pyproject.toml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/setup.cfg +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/commons.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/base/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/base/cal_measurement.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/base/content.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/base/shepherd.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/base/timezone.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/base/wrapper.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/_external_fixtures.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/energy_environment.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/firmware.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/content/firmware_datatype.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/experiment/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/experiment/experiment.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/experiment/observer_features.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/experiment/target_config.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/readme.md +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/task/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/task/emulation.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/task/firmware_mod.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/task/harvest.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/task/observer_tasks.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/task/programming.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/task/testbed_tasks.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/cape.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/cape_fixture.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/gpio.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/mcu.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/mcu_fixture.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/observer.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/observer_fixture.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/target.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/target_fixture.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/testbed.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/testbed/testbed_fixture.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/virtual_source_doc.txt +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/decoder_waveform/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/decoder_waveform/uart.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/fw_tools/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/fw_tools/converter.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/fw_tools/converter_elf.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/fw_tools/patcher.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/fw_tools/validation.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/inventory/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/inventory/python.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/inventory/system.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/inventory/target.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/logger.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/testbed_client/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/testbed_client/cache_path.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/testbed_client/client_abc_fix.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/testbed_client/client_web.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/testbed_client/fixtures.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/testbed_client/user_model.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/vsource/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/vsource/virtual_source_model.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core.egg-info/dependency_links.txt +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core.egg-info/requires.txt +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core.egg-info/top_level.txt +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core.egg-info/zip-safe +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/conftest.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/conftest.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_cal_data.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_cal_data_faulty.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_cal_meas.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_cal_meas_faulty1.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_cal_meas_faulty2.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_config_emulator.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_config_experiment.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_config_experiment_alternative.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_config_harvester.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_config_testbed.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/example_config_virtsource.yaml +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_base_models.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_content_fixtures.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_content_models.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_examples.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_experiment_models.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_task_generation.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_task_models.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_testbed_fixtures.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/data_models/test_testbed_models.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/decoder_waveform/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/decoder_waveform/test_decoder.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/fw_tools/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/fw_tools/build_msp.elf +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/fw_tools/build_nrf.elf +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/fw_tools/conftest.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/fw_tools/test_converter.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/fw_tools/test_patcher.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/fw_tools/test_validation.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/inventory/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/inventory/test_inventory.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/test_cal_hw.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/test_examples.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/test_logger.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/test_reader.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/test_writer.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/testbed_client/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/vsource/__init__.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/vsource/conftest.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/vsource/test_harvester.py +0 -0
- {shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/tests/vsource/test_z.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: shepherd_core
|
|
3
|
-
Version: 2024.
|
|
3
|
+
Version: 2024.8.1
|
|
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>
|
|
@@ -136,28 +136,30 @@ Notes:
|
|
|
136
136
|
The Library is available via PyPI and can be installed with
|
|
137
137
|
|
|
138
138
|
```shell
|
|
139
|
-
|
|
139
|
+
pip install shepherd-core -U
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
# or for the full experience (includes core)
|
|
142
|
+
pip install shepherd-data -U
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
For bleeding-edge-features or dev-work it is possible to install directly from GitHub-Sources (here `dev`-branch):
|
|
146
146
|
|
|
147
147
|
```Shell
|
|
148
148
|
pip install git+https://github.com/orgua/shepherd-datalib.git@dev#subdirectory=shepherd_core -U
|
|
149
|
+
# and on sheep with newer debian
|
|
150
|
+
pip install git+https://github.com/orgua/shepherd-datalib.git@dev#subdirectory=shepherd_core -U --break-system-packages
|
|
149
151
|
```
|
|
150
152
|
|
|
151
153
|
If you are working with ``.elf``-files (embedding into experiments) you make "objcopy" accessible to python. In Ubuntu, you can either install ``build-essential`` or ``binutils-$ARCH`` with arch being ``msp430`` or ``arm-none-eabi`` for the nRF52.
|
|
152
154
|
|
|
153
155
|
```shell
|
|
154
|
-
|
|
156
|
+
sudo apt install build-essential
|
|
155
157
|
```
|
|
156
158
|
|
|
157
159
|
For more advanced work with ``.elf``-files (modify value of symbols / target-ID) you should install
|
|
158
160
|
|
|
159
161
|
```shell
|
|
160
|
-
|
|
162
|
+
pip install shepherd-core[elf]
|
|
161
163
|
```
|
|
162
164
|
|
|
163
165
|
and also make sure the prereqs for the [pwntools](https://docs.pwntools.com/en/stable/install.html) are met.
|
|
@@ -165,7 +167,7 @@ and also make sure the prereqs for the [pwntools](https://docs.pwntools.com/en/s
|
|
|
165
167
|
For creating an inventory of the host-system you should install
|
|
166
168
|
|
|
167
169
|
```shell
|
|
168
|
-
|
|
170
|
+
pip install shepherd-core[inventory]
|
|
169
171
|
```
|
|
170
172
|
|
|
171
173
|
## Unittests
|
|
@@ -80,28 +80,30 @@ Notes:
|
|
|
80
80
|
The Library is available via PyPI and can be installed with
|
|
81
81
|
|
|
82
82
|
```shell
|
|
83
|
-
|
|
83
|
+
pip install shepherd-core -U
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
# or for the full experience (includes core)
|
|
86
|
+
pip install shepherd-data -U
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
For bleeding-edge-features or dev-work it is possible to install directly from GitHub-Sources (here `dev`-branch):
|
|
90
90
|
|
|
91
91
|
```Shell
|
|
92
92
|
pip install git+https://github.com/orgua/shepherd-datalib.git@dev#subdirectory=shepherd_core -U
|
|
93
|
+
# and on sheep with newer debian
|
|
94
|
+
pip install git+https://github.com/orgua/shepherd-datalib.git@dev#subdirectory=shepherd_core -U --break-system-packages
|
|
93
95
|
```
|
|
94
96
|
|
|
95
97
|
If you are working with ``.elf``-files (embedding into experiments) you make "objcopy" accessible to python. In Ubuntu, you can either install ``build-essential`` or ``binutils-$ARCH`` with arch being ``msp430`` or ``arm-none-eabi`` for the nRF52.
|
|
96
98
|
|
|
97
99
|
```shell
|
|
98
|
-
|
|
100
|
+
sudo apt install build-essential
|
|
99
101
|
```
|
|
100
102
|
|
|
101
103
|
For more advanced work with ``.elf``-files (modify value of symbols / target-ID) you should install
|
|
102
104
|
|
|
103
105
|
```shell
|
|
104
|
-
|
|
106
|
+
pip install shepherd-core[elf]
|
|
105
107
|
```
|
|
106
108
|
|
|
107
109
|
and also make sure the prereqs for the [pwntools](https://docs.pwntools.com/en/stable/install.html) are met.
|
|
@@ -109,7 +111,7 @@ and also make sure the prereqs for the [pwntools](https://docs.pwntools.com/en/s
|
|
|
109
111
|
For creating an inventory of the host-system you should install
|
|
110
112
|
|
|
111
113
|
```shell
|
|
112
|
-
|
|
114
|
+
pip install shepherd-core[inventory]
|
|
113
115
|
```
|
|
114
116
|
|
|
115
117
|
## Unittests
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Create a set of static artificial energy environments."""
|
|
2
|
+
|
|
3
|
+
from itertools import product
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
from tqdm import trange
|
|
8
|
+
|
|
9
|
+
from shepherd_core import Reader as ShpReader
|
|
10
|
+
from shepherd_core import Writer as ShpWriter
|
|
11
|
+
from shepherd_core import logger
|
|
12
|
+
|
|
13
|
+
# Config
|
|
14
|
+
voltages_V = [4.0, 2.0]
|
|
15
|
+
currents_A = [2e-3, 1e-3]
|
|
16
|
+
duration_s = 10
|
|
17
|
+
repetitions = 1
|
|
18
|
+
|
|
19
|
+
path_here = Path(__file__).parent.absolute()
|
|
20
|
+
|
|
21
|
+
for _v, _c in product(voltages_V, currents_A):
|
|
22
|
+
v_str = f"{round(_v * 1000)}mV"
|
|
23
|
+
c_str = f"{round(_c * 1000)}mA"
|
|
24
|
+
t_str = f"{round(duration_s * repetitions)}s"
|
|
25
|
+
name = f"eenv_static_{v_str}_{c_str}_{t_str}"
|
|
26
|
+
file_path = path_here / f"{name}.h5"
|
|
27
|
+
|
|
28
|
+
if file_path.exists():
|
|
29
|
+
logger.info("File exists, will skip: %s", file_path.name)
|
|
30
|
+
else:
|
|
31
|
+
with ShpWriter(file_path) as file:
|
|
32
|
+
file.store_hostname("artificial")
|
|
33
|
+
# values in SI units
|
|
34
|
+
timestamp_vector = np.arange(0.0, duration_s, file.sample_interval_ns / 1e9)
|
|
35
|
+
voltage_vector = np.linspace(_v, _v, int(file.samplerate_sps * duration_s))
|
|
36
|
+
current_vector = np.linspace(_c, _c, int(file.samplerate_sps * duration_s))
|
|
37
|
+
|
|
38
|
+
for idx in trange(repetitions, desc="generate"):
|
|
39
|
+
timestamps = idx * duration_s + timestamp_vector
|
|
40
|
+
file.append_iv_data_si(timestamps, voltage_vector, current_vector)
|
|
41
|
+
|
|
42
|
+
with ShpReader(file_path) as file:
|
|
43
|
+
file.save_metadata()
|
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
from contextlib import ExitStack
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
|
|
12
|
+
from shepherd_core import CalibrationHarvester
|
|
11
13
|
from shepherd_core import Reader
|
|
14
|
+
from shepherd_core import Writer
|
|
12
15
|
from shepherd_core.data_models import VirtualHarvesterConfig
|
|
13
16
|
from shepherd_core.data_models.content.virtual_harvester import HarvesterPRUConfig
|
|
14
17
|
from shepherd_core.vsource import VirtualHarvesterModel
|
|
@@ -32,6 +35,8 @@ hrv_list = [
|
|
|
32
35
|
"mppt_opt",
|
|
33
36
|
]
|
|
34
37
|
|
|
38
|
+
save_files: bool = True
|
|
39
|
+
|
|
35
40
|
# convert IVonne to IVCurve
|
|
36
41
|
if not file_ivcurve.exists():
|
|
37
42
|
with ivonne.Reader(file_ivonne) as db:
|
|
@@ -45,7 +50,7 @@ with Reader(file_ivcurve, verbose=False) as file:
|
|
|
45
50
|
I_in_max = max(I_in_max, _i.max())
|
|
46
51
|
print(
|
|
47
52
|
f"Input-file: \n"
|
|
48
|
-
f"\tE_in = {file.energy() * 1e3:.3f} mWs\n"
|
|
53
|
+
f"\tE_in = {file.energy() * 1e3:.3f} mWs (not representative)\n"
|
|
49
54
|
f"\tI_in_max = {I_in_max * 1e3:.3f} mA\n"
|
|
50
55
|
f"\twindow_size = {window_size} n\n",
|
|
51
56
|
)
|
|
@@ -53,21 +58,39 @@ with Reader(file_ivcurve, verbose=False) as file:
|
|
|
53
58
|
# Simulation
|
|
54
59
|
for hrv_name in hrv_list:
|
|
55
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
|
+
|
|
56
73
|
with Reader(file_ivcurve, verbose=False) as file:
|
|
57
74
|
hrv_config = VirtualHarvesterConfig(name=hrv_name)
|
|
58
75
|
hrv_pru = HarvesterPRUConfig.from_vhrv(
|
|
59
76
|
hrv_config,
|
|
60
77
|
for_emu=True,
|
|
61
78
|
dtype_in=file.get_datatype(),
|
|
62
|
-
window_size=file.get_window_samples(),
|
|
79
|
+
window_size=4 * file.get_window_samples(),
|
|
63
80
|
)
|
|
64
81
|
hrv = VirtualHarvesterModel(hrv_pru)
|
|
65
82
|
for _t, _v, _i in file.read_buffers():
|
|
83
|
+
# TODO: _t should be handed to new file without conversions
|
|
66
84
|
length = max(_v.size, _i.size)
|
|
67
85
|
for _n in range(length):
|
|
68
86
|
_v[_n], _i[_n] = hrv.ivcurve_sample(
|
|
69
87
|
_voltage_uV=_v[_n] * 10**6, _current_nA=_i[_n] * 10**9
|
|
70
88
|
)
|
|
71
89
|
E_out_Ws += (_v * _i).sum() * 1e-15 * file.sample_interval_s
|
|
72
|
-
|
|
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()
|
|
73
96
|
print(f"E_out = {E_out_Ws * 1e3:.3f} mWs -> {hrv_name}")
|
|
@@ -0,0 +1,86 @@
|
|
|
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()
|
|
@@ -32,45 +32,48 @@ RAW_MAX_ADC = 2**M_ADC - 1
|
|
|
32
32
|
RAW_MAX_DAC = 2**M_DAC - 1
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def adc_current_to_raw(current: float) -> int:
|
|
35
|
+
def adc_current_to_raw(current: float, *, limited: bool = True) -> int:
|
|
36
36
|
"""Convert back a current [A] to raw ADC value."""
|
|
37
37
|
# voltage on input of adc
|
|
38
38
|
val_adc = G_INST_AMP * R_SHT * current
|
|
39
39
|
# digital value according to ADC gain
|
|
40
40
|
val_raw = int(val_adc * (2**M_ADC) / (G_ADC_I * V_REF_ADC))
|
|
41
|
-
return min(max(val_raw, 0), 2**M_ADC - 1)
|
|
41
|
+
return min(max(val_raw, 0), 2**M_ADC - 1) if limited else val_raw
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def adc_raw_to_current(value: int) -> float:
|
|
44
|
+
def adc_raw_to_current(value: int, *, limited: bool = True) -> float:
|
|
45
45
|
"""Convert a raw ADC value to a current [A]."""
|
|
46
|
-
|
|
46
|
+
if limited:
|
|
47
|
+
value = min(max(value, 0), 2**M_ADC - 1)
|
|
47
48
|
# voltage on input of adc
|
|
48
49
|
val_adc = float(value) * (G_ADC_I * V_REF_ADC) / (2**M_ADC)
|
|
49
50
|
# current according to adc value
|
|
50
51
|
return val_adc / (R_SHT * G_INST_AMP)
|
|
51
52
|
|
|
52
53
|
|
|
53
|
-
def adc_voltage_to_raw(voltage: float) -> int:
|
|
54
|
+
def adc_voltage_to_raw(voltage: float, *, limited: bool = True) -> int:
|
|
54
55
|
"""Convert back a voltage [V] to raw ADC value."""
|
|
55
56
|
# digital value according to ADC gain
|
|
56
57
|
val_raw = int(voltage * (2**M_ADC) / (G_ADC_V * V_REF_ADC))
|
|
57
|
-
return min(max(val_raw, 0), 2**M_ADC - 1)
|
|
58
|
+
return min(max(val_raw, 0), 2**M_ADC - 1) if limited else val_raw
|
|
58
59
|
|
|
59
60
|
|
|
60
|
-
def adc_raw_to_voltage(value: int) -> float:
|
|
61
|
+
def adc_raw_to_voltage(value: int, *, limited: bool = True) -> float:
|
|
61
62
|
"""Convert a raw ADC value to a voltage [V]."""
|
|
62
|
-
|
|
63
|
+
if limited:
|
|
64
|
+
value = min(max(value, 0), 2**M_ADC - 1)
|
|
63
65
|
# voltage according to ADC value
|
|
64
66
|
return float(value) * (G_ADC_V * V_REF_ADC) / (2**M_ADC)
|
|
65
67
|
|
|
66
68
|
|
|
67
|
-
def dac_raw_to_voltage(value: int) -> float:
|
|
69
|
+
def dac_raw_to_voltage(value: int, *, limited: bool = True) -> float:
|
|
68
70
|
"""Convert back a raw DAC value to a voltage [V]."""
|
|
69
|
-
|
|
71
|
+
if limited:
|
|
72
|
+
value = min(max(value, 0), 2**M_DAC - 1)
|
|
70
73
|
return float(value) * (V_REF_DAC * G_DAC) / (2**M_DAC)
|
|
71
74
|
|
|
72
75
|
|
|
73
|
-
def dac_voltage_to_raw(voltage: float) -> int:
|
|
76
|
+
def dac_voltage_to_raw(voltage: float, *, limited: bool = True) -> int:
|
|
74
77
|
"""Convert a voltage [V] to raw DAC value."""
|
|
75
78
|
val_raw = int(voltage * (2**M_DAC) / (V_REF_DAC * G_DAC))
|
|
76
|
-
return min(max(val_raw, 0), 2**M_DAC - 1)
|
|
79
|
+
return min(max(val_raw, 0), 2**M_DAC - 1) if limited else val_raw
|
{shepherd_core-2024.7.3 → shepherd_core-2024.8.1}/shepherd_core/data_models/base/calibration.py
RENAMED
|
@@ -51,6 +51,7 @@ class CalibrationPair(ShpModel):
|
|
|
51
51
|
|
|
52
52
|
gain: PositiveFloat
|
|
53
53
|
offset: float = 0
|
|
54
|
+
unit: Optional[str] = None # TODO: add units when used
|
|
54
55
|
|
|
55
56
|
def raw_to_si(self, values_raw: Calc_t, *, allow_negative: bool = True) -> Calc_t:
|
|
56
57
|
"""Convert between physical units and raw unsigned integers."""
|
|
@@ -77,14 +78,11 @@ class CalibrationPair(ShpModel):
|
|
|
77
78
|
return values_raw
|
|
78
79
|
|
|
79
80
|
@classmethod
|
|
80
|
-
def from_fn(cls, fn: Callable) -> Self:
|
|
81
|
+
def from_fn(cls, fn: Callable, unit: Optional[str] = None) -> Self:
|
|
81
82
|
"""Probe linear function to determine scaling values."""
|
|
82
|
-
offset = fn(0)
|
|
83
|
-
gain_inv = fn(1.0) - offset
|
|
84
|
-
return cls(
|
|
85
|
-
gain=1.0 / float(gain_inv),
|
|
86
|
-
offset=-float(offset) / gain_inv,
|
|
87
|
-
)
|
|
83
|
+
offset = fn(0, limited=False)
|
|
84
|
+
gain_inv = fn(1.0, limited=False) - offset
|
|
85
|
+
return cls(gain=1.0 / float(gain_inv), offset=-float(offset) / gain_inv, unit=unit)
|
|
88
86
|
|
|
89
87
|
|
|
90
88
|
cal_hrv_legacy = { # legacy translator
|
|
@@ -98,10 +96,10 @@ cal_hrv_legacy = { # legacy translator
|
|
|
98
96
|
class CalibrationHarvester(ShpModel):
|
|
99
97
|
"""Container for all calibration-pairs for that device."""
|
|
100
98
|
|
|
101
|
-
dac_V_Hrv: CalibrationPair = CalibrationPair.from_fn(dac_voltage_to_raw)
|
|
102
|
-
dac_V_Sim: CalibrationPair = CalibrationPair.from_fn(dac_voltage_to_raw)
|
|
103
|
-
adc_V_Sense: CalibrationPair = CalibrationPair.from_fn(adc_voltage_to_raw)
|
|
104
|
-
adc_C_Hrv: CalibrationPair = CalibrationPair.from_fn(adc_current_to_raw)
|
|
99
|
+
dac_V_Hrv: CalibrationPair = CalibrationPair.from_fn(dac_voltage_to_raw, unit="V")
|
|
100
|
+
dac_V_Sim: CalibrationPair = CalibrationPair.from_fn(dac_voltage_to_raw, unit="V")
|
|
101
|
+
adc_V_Sense: CalibrationPair = CalibrationPair.from_fn(adc_voltage_to_raw, unit="V")
|
|
102
|
+
adc_C_Hrv: CalibrationPair = CalibrationPair.from_fn(adc_current_to_raw, unit="A")
|
|
105
103
|
|
|
106
104
|
def export_for_sysfs(self) -> dict:
|
|
107
105
|
"""Convert and write the essential data.
|
|
@@ -142,10 +140,10 @@ class CalibrationEmulator(ShpModel):
|
|
|
142
140
|
Differentiates between both target-ports A/B.
|
|
143
141
|
"""
|
|
144
142
|
|
|
145
|
-
dac_V_A: CalibrationPair = CalibrationPair.from_fn(dac_voltage_to_raw)
|
|
146
|
-
dac_V_B: CalibrationPair = CalibrationPair.from_fn(dac_voltage_to_raw)
|
|
147
|
-
adc_C_A: CalibrationPair = CalibrationPair.from_fn(adc_current_to_raw)
|
|
148
|
-
adc_C_B: CalibrationPair = CalibrationPair.from_fn(adc_current_to_raw)
|
|
143
|
+
dac_V_A: CalibrationPair = CalibrationPair.from_fn(dac_voltage_to_raw, unit="V")
|
|
144
|
+
dac_V_B: CalibrationPair = CalibrationPair.from_fn(dac_voltage_to_raw, unit="V")
|
|
145
|
+
adc_C_A: CalibrationPair = CalibrationPair.from_fn(adc_current_to_raw, unit="A")
|
|
146
|
+
adc_C_B: CalibrationPair = CalibrationPair.from_fn(adc_current_to_raw, unit="A")
|
|
149
147
|
|
|
150
148
|
def export_for_sysfs(self) -> dict:
|
|
151
149
|
"""Convert and write the essential data.
|
|
@@ -232,10 +230,11 @@ class CalibrationCape(ShpModel):
|
|
|
232
230
|
|
|
233
231
|
"""
|
|
234
232
|
dv = cls().model_dump(include={"harvester", "emulator"})
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
lw1 = list(dict_generator(dv))
|
|
234
|
+
lw2 = [elem for elem in lw1 if isinstance(elem[-1], float)]
|
|
235
|
+
values = struct.unpack(">" + len(lw2) * "d", data)
|
|
237
236
|
# ⤷ X => double float, big endian
|
|
238
|
-
for _i, walk in enumerate(
|
|
237
|
+
for _i, walk in enumerate(lw2):
|
|
239
238
|
# hardcoded fixed depth ... bad but easy
|
|
240
239
|
dv[walk[0]][walk[1]][walk[2]] = float(values[_i])
|
|
241
240
|
dv["cape"] = cape
|
|
@@ -251,18 +250,18 @@ class CalibrationCape(ShpModel):
|
|
|
251
250
|
|
|
252
251
|
"""
|
|
253
252
|
lw = list(dict_generator(self.model_dump(include={"harvester", "emulator"})))
|
|
254
|
-
values = [walk[-1] for walk in lw]
|
|
255
|
-
return struct.pack(">" + len(
|
|
253
|
+
values = [walk[-1] for walk in lw if isinstance(walk[-1], float)]
|
|
254
|
+
return struct.pack(">" + len(values) * "d", *values)
|
|
256
255
|
|
|
257
256
|
|
|
258
257
|
class CalibrationSeries(ShpModel):
|
|
259
258
|
"""Cal-Data for a typical recording of a testbed experiment."""
|
|
260
259
|
|
|
261
|
-
voltage: CalibrationPair = CalibrationPair(gain=3 * 1e-9)
|
|
260
|
+
voltage: CalibrationPair = CalibrationPair(gain=3 * 1e-9, unit="V")
|
|
262
261
|
# ⤷ default allows 0 - 12 V in 3 nV-Steps
|
|
263
|
-
current: CalibrationPair = CalibrationPair(gain=250 * 1e-12)
|
|
262
|
+
current: CalibrationPair = CalibrationPair(gain=250 * 1e-12, unit="A")
|
|
264
263
|
# ⤷ default allows 0 - 1 A in 250 pA - Steps
|
|
265
|
-
time: CalibrationPair = CalibrationPair(gain=1e-9)
|
|
264
|
+
time: CalibrationPair = CalibrationPair(gain=1e-9, unit="s")
|
|
266
265
|
# ⤷ default = nanoseconds
|
|
267
266
|
|
|
268
267
|
@classmethod
|
|
@@ -274,7 +273,7 @@ class CalibrationSeries(ShpModel):
|
|
|
274
273
|
emu_port_a: bool = True,
|
|
275
274
|
) -> Self:
|
|
276
275
|
if isinstance(cal, CalibrationHarvester):
|
|
277
|
-
return cls(voltage=cal.adc_V_Sense, current=cal.
|
|
276
|
+
return cls(voltage=cal.adc_V_Sense, current=cal.adc_C_Hrv)
|
|
278
277
|
if emu_port_a:
|
|
279
278
|
return cls(voltage=cal.dac_V_A, current=cal.adc_C_A)
|
|
280
279
|
return cls(voltage=cal.dac_V_B, current=cal.adc_C_B)
|
|
@@ -149,20 +149,27 @@ class VirtualHarvesterConfig(ContentModel, title="Config for the Harvester"):
|
|
|
149
149
|
|
|
150
150
|
def calc_window_size(
|
|
151
151
|
self,
|
|
152
|
-
dtype_in: Optional[EnergyDType] =
|
|
152
|
+
dtype_in: Optional[EnergyDType] = None,
|
|
153
153
|
*,
|
|
154
154
|
for_emu: bool,
|
|
155
155
|
) -> int:
|
|
156
|
-
if for_emu:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
raise NotImplementedError
|
|
156
|
+
if not for_emu:
|
|
157
|
+
# TODO: should be named 'for_ivcurve_recording'
|
|
158
|
+
# TODO: add extra variable to distinguish step_count
|
|
159
|
+
# and window_size (currently mixed together)
|
|
160
|
+
# only used by ivcurve algo (in ADC-Mode)
|
|
161
|
+
return self.samples_n
|
|
163
162
|
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
if dtype_in is None:
|
|
164
|
+
dtype_in = self.get_datatype()
|
|
165
|
+
|
|
166
|
+
if dtype_in == EnergyDType.ivcurve:
|
|
167
|
+
return self.samples_n * (1 + self.wait_cycles)
|
|
168
|
+
if dtype_in == EnergyDType.ivsample:
|
|
169
|
+
return 0
|
|
170
|
+
if dtype_in == EnergyDType.isc_voc:
|
|
171
|
+
return 2 * (1 + self.wait_cycles)
|
|
172
|
+
raise NotImplementedError
|
|
166
173
|
|
|
167
174
|
|
|
168
175
|
u32 = Annotated[int, Field(ge=0, lt=2**32)]
|
|
@@ -234,7 +241,7 @@ class HarvesterPRUConfig(ShpModel):
|
|
|
234
241
|
dtype_in = EnergyDType[dtype_in]
|
|
235
242
|
if for_emu and dtype_in not in {EnergyDType.ivsample, EnergyDType.ivcurve}:
|
|
236
243
|
raise NotImplementedError
|
|
237
|
-
|
|
244
|
+
|
|
238
245
|
interval_ms, duration_ms = data.calc_timings_ms(for_emu=for_emu)
|
|
239
246
|
return cls(
|
|
240
247
|
algorithm=data.calc_algorithm_num(for_emu=for_emu),
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
id: 1010
|
|
20
20
|
name: ivcurve
|
|
21
21
|
description: Postpone harvesting by sampling ivcurves (voltage stepped as sawtooth-wave)
|
|
22
|
-
comment: ~
|
|
22
|
+
comment: ~110 Hz, Between 50 & 60 Hz line-frequency to avoid standing waves
|
|
23
23
|
inherit_from: neutral
|
|
24
24
|
algorithm: ivcurve
|
|
25
|
-
samples_n:
|
|
25
|
+
samples_n: 909
|
|
26
26
|
voltage_min_mV: 0
|
|
27
27
|
voltage_max_mV: 5000
|
|
28
|
-
wait_cycles:
|
|
28
|
+
wait_cycles: 0
|
|
29
29
|
rising: false # downward sawtooth seems to have advantages for solar cells
|
|
30
30
|
# todo: also add switch for sawtooth- vs triangle-wave?
|
|
31
31
|
# todo: could also include a version with dynamic upper-boundary, varied if voc is reached very early
|
|
@@ -38,20 +38,17 @@
|
|
|
38
38
|
|
|
39
39
|
- datatype: VirtualHarvesterConfig
|
|
40
40
|
parameters:
|
|
41
|
-
id:
|
|
42
|
-
name:
|
|
43
|
-
comment: Name relates to curves per second
|
|
41
|
+
id: 1013
|
|
42
|
+
name: iv110 # synonym
|
|
44
43
|
inherit_from: ivcurve
|
|
45
|
-
samples_n: 100
|
|
46
|
-
wait_cycles: 0
|
|
47
44
|
|
|
48
45
|
- datatype: VirtualHarvesterConfig
|
|
49
46
|
parameters:
|
|
50
|
-
id:
|
|
51
|
-
name:
|
|
52
|
-
comment:
|
|
47
|
+
id: 1012
|
|
48
|
+
name: iv1000
|
|
49
|
+
comment: Name relates to curves per second
|
|
53
50
|
inherit_from: ivcurve
|
|
54
|
-
samples_n:
|
|
51
|
+
samples_n: 100
|
|
55
52
|
wait_cycles: 0
|
|
56
53
|
|
|
57
54
|
- datatype: VirtualHarvesterConfig
|
|
@@ -61,7 +58,7 @@
|
|
|
61
58
|
description: Postpone harvesting by sampling short circuit current & open circuit voltage
|
|
62
59
|
inherit_from: neutral
|
|
63
60
|
algorithm: isc_voc
|
|
64
|
-
wait_cycles:
|
|
61
|
+
wait_cycles: 4 # results in 10 kHz (isc, wait, voc, wait)
|
|
65
62
|
|
|
66
63
|
- datatype: VirtualHarvesterConfig
|
|
67
64
|
parameters:
|
|
@@ -76,6 +76,8 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
|
|
|
76
76
|
# final (always last) stage to compensate undetectable current spikes
|
|
77
77
|
# when enabling power for target
|
|
78
78
|
C_output_uF: Annotated[float, Field(ge=0, le=4.29e6)] = 1.0
|
|
79
|
+
# TODO: C_output is handled internally as delta-V, but should be a I_transient
|
|
80
|
+
# that makes it visible in simulation as additional i_out_drain
|
|
79
81
|
|
|
80
82
|
# Extra
|
|
81
83
|
V_output_log_gpio_threshold_mV: Annotated[float, Field(ge=0, le=4.29e6)] = 1_400
|
|
@@ -93,7 +95,7 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
|
|
|
93
95
|
# influence of cap-voltage is not implemented
|
|
94
96
|
LUT_input_V_min_log2_uV: Annotated[int, Field(ge=0, le=20)] = 0
|
|
95
97
|
# ⤷ 2^7 = 128 uV -> LUT[0][:] is for inputs < 128 uV
|
|
96
|
-
LUT_input_I_min_log2_nA: Annotated[int, Field(ge=
|
|
98
|
+
LUT_input_I_min_log2_nA: Annotated[int, Field(ge=1, le=20)] = 1
|
|
97
99
|
# ⤷ 2^8 = 256 nA -> LUT[:][0] is for inputs < 256 nA
|
|
98
100
|
|
|
99
101
|
# Buck Converter
|
|
@@ -103,7 +105,7 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
|
|
|
103
105
|
|
|
104
106
|
LUT_output_efficiency: LUT1D = 12 * [1.00]
|
|
105
107
|
# ⤷ array[12] depending on output_current
|
|
106
|
-
LUT_output_I_min_log2_nA: Annotated[int, Field(ge=
|
|
108
|
+
LUT_output_I_min_log2_nA: Annotated[int, Field(ge=1, le=20)] = 1
|
|
107
109
|
# ⤷ 2^8 = 256 nA -> LUT[0] is for inputs < 256 nA, see notes on LUT_input for explanation
|
|
108
110
|
|
|
109
111
|
@model_validator(mode="before")
|
|
@@ -318,8 +320,8 @@ class ConverterPRUConfig(ShpModel):
|
|
|
318
320
|
V_buck_drop_uV=round(data.V_buck_drop_mV * 1e3),
|
|
319
321
|
# LUTs
|
|
320
322
|
LUT_input_V_min_log2_uV=data.LUT_input_V_min_log2_uV,
|
|
321
|
-
LUT_input_I_min_log2_nA=data.LUT_input_I_min_log2_nA,
|
|
322
|
-
LUT_output_I_min_log2_nA=data.LUT_output_I_min_log2_nA,
|
|
323
|
+
LUT_input_I_min_log2_nA=data.LUT_input_I_min_log2_nA - 1, # sub-1 due to later log2-op
|
|
324
|
+
LUT_output_I_min_log2_nA=data.LUT_output_I_min_log2_nA - 1, # sub-1 due to later log2
|
|
323
325
|
LUT_inp_efficiency_n8=[
|
|
324
326
|
[min(255, round(256 * ival)) for ival in il] for il in data.LUT_input_efficiency
|
|
325
327
|
],
|
|
@@ -56,16 +56,18 @@
|
|
|
56
56
|
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
57
57
|
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
58
58
|
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
59
|
-
]
|
|
59
|
+
]
|
|
60
|
+
# input-array[12][12] depending on array[inp_voltage][log(inp_current)],
|
|
61
|
+
# influence of cap-voltage is not implemented
|
|
60
62
|
LUT_input_V_min_log2_uV: 0 # 2^7 = 128 uV -> array[0] is for inputs < 128 uV
|
|
61
|
-
LUT_input_I_min_log2_nA:
|
|
63
|
+
LUT_input_I_min_log2_nA: 1 # 2^8 = 256 nA -> array[0] is for inputs < 256 nA
|
|
62
64
|
|
|
63
65
|
# Buck-converter
|
|
64
66
|
V_output_mV: 2400
|
|
65
67
|
V_buck_drop_mV: 0.0 # simulate LDO min voltage differential or output-diode
|
|
66
68
|
|
|
67
69
|
LUT_output_efficiency: [ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ] # array[12] depending on output_current
|
|
68
|
-
LUT_output_I_min_log2_nA:
|
|
70
|
+
LUT_output_I_min_log2_nA: 1 # 2^8 = 256 nA -> array[0] is for inputs < 256 nA, see notes on LUT_input for explanation
|
|
69
71
|
|
|
70
72
|
owner: Ingmar
|
|
71
73
|
group: NES Lab
|
|
@@ -114,7 +116,7 @@
|
|
|
114
116
|
parameters:
|
|
115
117
|
id: 1020
|
|
116
118
|
name: BQ25504
|
|
117
|
-
description: TI BQ25504 with integrated boost-converter
|
|
119
|
+
description: TI BQ25504 with integrated boost-converter. Values are taken from the DK-Board.
|
|
118
120
|
inherit_from: neutral # to complete undefined vars
|
|
119
121
|
enable_boost: true # if false -> v_intermediate = v_input, output-switch-hysteresis is still usable
|
|
120
122
|
|
|
@@ -124,16 +126,16 @@
|
|
|
124
126
|
V_input_max_mV: 3000
|
|
125
127
|
I_input_max_mA: 100
|
|
126
128
|
|
|
127
|
-
C_intermediate_uF:
|
|
129
|
+
C_intermediate_uF: 100.0 # primary storage-Cap
|
|
128
130
|
V_intermediate_init_mV: 3000 # allow a proper / fast startup
|
|
129
131
|
I_intermediate_leak_nA: 330
|
|
130
132
|
|
|
131
|
-
V_intermediate_enable_threshold_mV:
|
|
132
|
-
V_intermediate_disable_threshold_mV:
|
|
133
|
+
V_intermediate_enable_threshold_mV: 1000 # -> target gets connected (hysteresis-combo with next value)
|
|
134
|
+
V_intermediate_disable_threshold_mV: 0 # -> target gets disconnected
|
|
133
135
|
interval_check_thresholds_ms: 64.0 # some BQs check every 64 ms if output should be disconnected
|
|
134
136
|
|
|
135
137
|
V_pwr_good_enable_threshold_mV: 2800 # target is informed by pwr-good on output-pin (hysteresis) -> for intermediate voltage
|
|
136
|
-
V_pwr_good_disable_threshold_mV:
|
|
138
|
+
V_pwr_good_disable_threshold_mV: 2340
|
|
137
139
|
immediate_pwr_good_signal: false # 1: activate instant schmitt-trigger, 0: stay in interval for checking thresholds
|
|
138
140
|
|
|
139
141
|
# Boost Converter
|