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