shepherd-core 2024.4.1__py3-none-any.whl → 2024.5.1__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.
- shepherd_core/__init__.py +3 -3
- shepherd_core/calibration_hw_def.py +9 -1
- shepherd_core/commons.py +2 -0
- shepherd_core/data_models/__init__.py +11 -0
- shepherd_core/data_models/base/__init__.py +4 -1
- shepherd_core/data_models/base/cal_measurement.py +18 -6
- shepherd_core/data_models/base/calibration.py +39 -15
- shepherd_core/data_models/base/content.py +10 -2
- shepherd_core/data_models/base/shepherd.py +21 -12
- shepherd_core/data_models/base/timezone.py +5 -0
- shepherd_core/data_models/base/wrapper.py +3 -3
- shepherd_core/data_models/content/__init__.py +5 -4
- shepherd_core/data_models/content/_external_fixtures.yaml +410 -0
- shepherd_core/data_models/content/energy_environment.py +7 -5
- shepherd_core/data_models/content/energy_environment_fixture.yaml +53 -0
- shepherd_core/data_models/content/firmware.py +12 -5
- shepherd_core/data_models/content/firmware_datatype.py +7 -0
- shepherd_core/data_models/content/virtual_harvester.py +24 -19
- shepherd_core/data_models/content/virtual_harvester_fixture.yaml +160 -0
- shepherd_core/data_models/content/virtual_source.py +22 -10
- shepherd_core/data_models/content/virtual_source_fixture.yaml +230 -0
- shepherd_core/data_models/experiment/__init__.py +5 -4
- shepherd_core/data_models/experiment/experiment.py +7 -6
- shepherd_core/data_models/experiment/observer_features.py +14 -7
- shepherd_core/data_models/experiment/target_config.py +11 -7
- shepherd_core/data_models/readme.md +88 -0
- shepherd_core/data_models/task/__init__.py +10 -3
- shepherd_core/data_models/task/emulation.py +10 -7
- shepherd_core/data_models/task/firmware_mod.py +4 -2
- shepherd_core/data_models/task/harvest.py +5 -4
- shepherd_core/data_models/task/observer_tasks.py +3 -1
- shepherd_core/data_models/task/programming.py +3 -1
- shepherd_core/data_models/task/testbed_tasks.py +3 -1
- shepherd_core/data_models/testbed/__init__.py +5 -2
- shepherd_core/data_models/testbed/cape.py +7 -5
- shepherd_core/data_models/testbed/cape_fixture.yaml +94 -0
- shepherd_core/data_models/testbed/gpio.py +10 -8
- shepherd_core/data_models/testbed/gpio_fixture.yaml +166 -0
- shepherd_core/data_models/testbed/mcu.py +9 -9
- shepherd_core/data_models/testbed/mcu_fixture.yaml +19 -0
- shepherd_core/data_models/testbed/observer.py +9 -4
- shepherd_core/data_models/testbed/observer_fixture.yaml +221 -0
- shepherd_core/data_models/testbed/target.py +4 -2
- shepherd_core/data_models/testbed/target_fixture.yaml +137 -0
- shepherd_core/data_models/testbed/testbed.py +5 -2
- shepherd_core/data_models/testbed/testbed_fixture.yaml +25 -0
- shepherd_core/decoder_waveform/__init__.py +2 -0
- shepherd_core/decoder_waveform/uart.py +43 -25
- shepherd_core/fw_tools/__init__.py +2 -0
- shepherd_core/fw_tools/converter.py +20 -9
- shepherd_core/fw_tools/converter_elf.py +3 -0
- shepherd_core/fw_tools/patcher.py +17 -5
- shepherd_core/fw_tools/validation.py +27 -6
- shepherd_core/inventory/__init__.py +15 -5
- shepherd_core/inventory/python.py +4 -0
- shepherd_core/inventory/system.py +6 -2
- shepherd_core/inventory/target.py +4 -0
- shepherd_core/logger.py +5 -0
- shepherd_core/reader.py +38 -23
- shepherd_core/testbed_client/__init__.py +2 -0
- shepherd_core/testbed_client/cache_path.py +2 -0
- shepherd_core/testbed_client/client.py +15 -8
- shepherd_core/testbed_client/fixtures.py +27 -11
- shepherd_core/testbed_client/user_model.py +8 -3
- shepherd_core/vsource/__init__.py +2 -0
- shepherd_core/vsource/virtual_converter_model.py +10 -3
- shepherd_core/vsource/virtual_harvester_model.py +7 -1
- shepherd_core/vsource/virtual_source_model.py +9 -5
- shepherd_core/writer.py +26 -21
- {shepherd_core-2024.4.1.dist-info → shepherd_core-2024.5.1.dist-info}/METADATA +2 -1
- shepherd_core-2024.5.1.dist-info/RECORD +75 -0
- shepherd_core-2024.4.1.dist-info/RECORD +0 -64
- /shepherd_core/data_models/{doc_virtual_source.py → virtual_source_doc.txt} +0 -0
- {shepherd_core-2024.4.1.dist-info → shepherd_core-2024.5.1.dist-info}/WHEEL +0 -0
- {shepherd_core-2024.4.1.dist-info → shepherd_core-2024.5.1.dist-info}/top_level.txt +0 -0
- {shepherd_core-2024.4.1.dist-info → shepherd_core-2024.5.1.dist-info}/zip-safe +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# info:
|
|
2
|
+
# - compendium of all parameters & description
|
|
3
|
+
# - look into the implementation to see which parameters are used
|
|
4
|
+
# - base for neutral fallback values if provided yml is sparse
|
|
5
|
+
# - -> it is encouraged to omit redundant parameters in your own implementation
|
|
6
|
+
- datatype: VirtualHarvesterConfig
|
|
7
|
+
parameters:
|
|
8
|
+
id: 1000
|
|
9
|
+
name: neutral
|
|
10
|
+
owner: Ingmar
|
|
11
|
+
group: NES Lab
|
|
12
|
+
visible2group: true
|
|
13
|
+
visible2all: true
|
|
14
|
+
created: 2022-12-12 12:12:12
|
|
15
|
+
updated_last: 2022-12-12 12:12:12
|
|
16
|
+
|
|
17
|
+
- datatype: VirtualHarvesterConfig
|
|
18
|
+
parameters:
|
|
19
|
+
id: 1010
|
|
20
|
+
name: ivcurve
|
|
21
|
+
description: Postpone harvesting by sampling ivcurves (voltage stepped as sawtooth-wave)
|
|
22
|
+
comment: ~200 Hz
|
|
23
|
+
inherit_from: neutral
|
|
24
|
+
algorithm: ivcurve
|
|
25
|
+
samples_n: 250
|
|
26
|
+
voltage_min_mV: 0
|
|
27
|
+
voltage_max_mV: 5000
|
|
28
|
+
wait_cycles: 1 # results in 200 Hz (= 100kHz /(2*250))
|
|
29
|
+
rising: false # downward sawtooth seems to have advantages for solar cells
|
|
30
|
+
# todo: also add switch for sawtooth- vs triangle-wave?
|
|
31
|
+
# todo: could also include a version with dynamic upper-boundary, varied if voc is reached very early
|
|
32
|
+
|
|
33
|
+
- datatype: VirtualHarvesterConfig
|
|
34
|
+
parameters:
|
|
35
|
+
id: 1011
|
|
36
|
+
name: ivcurves # synonym
|
|
37
|
+
inherit_from: ivcurve
|
|
38
|
+
|
|
39
|
+
- datatype: VirtualHarvesterConfig
|
|
40
|
+
parameters:
|
|
41
|
+
id: 1012
|
|
42
|
+
name: iv1000
|
|
43
|
+
comment: Name relates to curves per second
|
|
44
|
+
inherit_from: ivcurve
|
|
45
|
+
samples_n: 100
|
|
46
|
+
wait_cycles: 0
|
|
47
|
+
|
|
48
|
+
- datatype: VirtualHarvesterConfig
|
|
49
|
+
parameters:
|
|
50
|
+
id: 1013
|
|
51
|
+
name: iv110
|
|
52
|
+
comment: Between 50 & 60 Hz line-frequency to avoid standing waves
|
|
53
|
+
inherit_from: ivcurve
|
|
54
|
+
samples_n: 909
|
|
55
|
+
wait_cycles: 0
|
|
56
|
+
|
|
57
|
+
- datatype: VirtualHarvesterConfig
|
|
58
|
+
parameters:
|
|
59
|
+
id: 1020
|
|
60
|
+
name: isc_voc
|
|
61
|
+
description: Postpone harvesting by sampling short circuit current & open circuit voltage
|
|
62
|
+
inherit_from: neutral
|
|
63
|
+
algorithm: isc_voc
|
|
64
|
+
wait_cycles: 1 # results in 25 kHz (isc, wait, voc, wait)
|
|
65
|
+
|
|
66
|
+
- datatype: VirtualHarvesterConfig
|
|
67
|
+
parameters:
|
|
68
|
+
id: 1030
|
|
69
|
+
name: cv20
|
|
70
|
+
description: Harvesting with constant Voltage
|
|
71
|
+
inherit_from: neutral
|
|
72
|
+
algorithm: cv
|
|
73
|
+
voltage_mV: 2000
|
|
74
|
+
|
|
75
|
+
- datatype: VirtualHarvesterConfig
|
|
76
|
+
parameters:
|
|
77
|
+
id: 1031
|
|
78
|
+
name: cv24
|
|
79
|
+
inherit_from: cv20
|
|
80
|
+
voltage_mV: 2400
|
|
81
|
+
|
|
82
|
+
- datatype: VirtualHarvesterConfig
|
|
83
|
+
parameters:
|
|
84
|
+
id: 1032
|
|
85
|
+
name: cv33
|
|
86
|
+
inherit_from: cv20
|
|
87
|
+
voltage_mV: 3300
|
|
88
|
+
|
|
89
|
+
- datatype: VirtualHarvesterConfig
|
|
90
|
+
parameters:
|
|
91
|
+
id: 1032
|
|
92
|
+
name: cv10
|
|
93
|
+
inherit_from: cv20
|
|
94
|
+
voltage_mV: 1000
|
|
95
|
+
|
|
96
|
+
- datatype: VirtualHarvesterConfig
|
|
97
|
+
parameters:
|
|
98
|
+
id: 1040
|
|
99
|
+
name: mppt_voc
|
|
100
|
+
description: MPPT based on open circuit voltage for solar
|
|
101
|
+
inherit_from: neutral
|
|
102
|
+
algorithm: mppt_voc
|
|
103
|
+
setpoint_n: 0.76
|
|
104
|
+
interval_ms: 100 # between measurements
|
|
105
|
+
duration_ms: 1.2 # solar can overshoot when load is removed
|
|
106
|
+
current_limit_uA: 5 # boundary for detecting open circuit in emulated version (working on IV-Curves)
|
|
107
|
+
|
|
108
|
+
- datatype: VirtualHarvesterConfig
|
|
109
|
+
parameters:
|
|
110
|
+
id: 1041
|
|
111
|
+
name: mppt_bq
|
|
112
|
+
description: MPPT of TI BQ-Converters for solar
|
|
113
|
+
inherit_from: mppt_voc
|
|
114
|
+
setpoint_n: 0.76
|
|
115
|
+
interval_ms: 16000 # between measurements
|
|
116
|
+
duration_ms: 256 # of measurement
|
|
117
|
+
|
|
118
|
+
- datatype: VirtualHarvesterConfig
|
|
119
|
+
parameters:
|
|
120
|
+
id: 1042
|
|
121
|
+
name: mppt_bqt
|
|
122
|
+
description: MPPT of TI BQ-Converters for thermoelectric
|
|
123
|
+
inherit_from: mppt_voc
|
|
124
|
+
setpoint_n: 0.50
|
|
125
|
+
interval_ms: 16000 # between measurements
|
|
126
|
+
duration_ms: 256 # of measurement
|
|
127
|
+
|
|
128
|
+
- datatype: VirtualHarvesterConfig
|
|
129
|
+
parameters:
|
|
130
|
+
id: 1043
|
|
131
|
+
name: mppt_bq_solar # explicit naming
|
|
132
|
+
inherit_from: mppt_bq
|
|
133
|
+
|
|
134
|
+
- datatype: VirtualHarvesterConfig
|
|
135
|
+
parameters:
|
|
136
|
+
id: 1044
|
|
137
|
+
name: mppt_bq_thermoelectric # explicit naming
|
|
138
|
+
inherit_from: mppt_bqt
|
|
139
|
+
|
|
140
|
+
- datatype: VirtualHarvesterConfig
|
|
141
|
+
parameters:
|
|
142
|
+
id: 1045
|
|
143
|
+
name: mppt_po
|
|
144
|
+
description: MPPT based on perturb & observe algorithm
|
|
145
|
+
inherit_from: neutral
|
|
146
|
+
algorithm: mppt_po
|
|
147
|
+
voltage_min_mV: 0
|
|
148
|
+
voltage_max_mV: 5000
|
|
149
|
+
voltage_step_mV: 10
|
|
150
|
+
interval_ms: 18 # between steps
|
|
151
|
+
|
|
152
|
+
- datatype: VirtualHarvesterConfig
|
|
153
|
+
parameters:
|
|
154
|
+
id: 1046
|
|
155
|
+
name: mppt_opt
|
|
156
|
+
description: Power-Optimum with very fast PO-Variant (harvesting) or special max-pwr-picker (emulator / ivcurve)
|
|
157
|
+
inherit_from: mppt_po
|
|
158
|
+
algorithm: mppt_opt
|
|
159
|
+
voltage_step_mV: 1
|
|
160
|
+
interval_ms: 0.01
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Generalized virtual source data models."""
|
|
2
|
+
|
|
1
3
|
from typing import List
|
|
2
4
|
|
|
3
5
|
from pydantic import Field
|
|
@@ -8,8 +10,8 @@ from typing_extensions import Self
|
|
|
8
10
|
from ...commons import samplerate_sps_default
|
|
9
11
|
from ...logger import logger
|
|
10
12
|
from ...testbed_client import tb_client
|
|
11
|
-
from .. import ShpModel
|
|
12
13
|
from ..base.content import ContentModel
|
|
14
|
+
from ..base.shepherd import ShpModel
|
|
13
15
|
from .virtual_harvester import HarvesterPRUConfig
|
|
14
16
|
from .virtual_harvester import VirtualHarvesterConfig
|
|
15
17
|
|
|
@@ -21,9 +23,11 @@ LUT2D = Annotated[List[LUT1D], Field(min_length=LUT_SIZE, max_length=LUT_SIZE)]
|
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
|
|
24
|
-
"""The
|
|
25
|
-
|
|
26
|
-
If not already done, the energy will be harvested and
|
|
26
|
+
"""The vSrc uses the energy environment (file) for supplying the Target Node.
|
|
27
|
+
|
|
28
|
+
If not already done, the energy will be harvested and
|
|
29
|
+
then converted during the experiment.
|
|
30
|
+
|
|
27
31
|
The converter-stage is software defined and offers:
|
|
28
32
|
- buck-boost-combinations,
|
|
29
33
|
- a simple diode + resistor and
|
|
@@ -117,9 +121,15 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
|
|
|
117
121
|
return self
|
|
118
122
|
|
|
119
123
|
def calc_internal_states(self) -> dict:
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
"""Update the model-states for the capacitor and other elements.
|
|
125
|
+
|
|
126
|
+
This also compensates for current-surge of real capacitors
|
|
127
|
+
when the converter gets turned on:
|
|
128
|
+
|
|
129
|
+
- surges are hard to detect & record
|
|
130
|
+
- this can be const value, because
|
|
131
|
+
- the converter always turns on with "V_storage_enable_threshold_uV".
|
|
132
|
+
|
|
123
133
|
TODO: currently neglecting delay after disabling converter, boost
|
|
124
134
|
only has simpler formula, second enabling when V_Cap >= V_out
|
|
125
135
|
|
|
@@ -189,7 +199,7 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
|
|
|
189
199
|
return values
|
|
190
200
|
|
|
191
201
|
def calc_converter_mode(self, *, log_intermediate_node: bool) -> int:
|
|
192
|
-
"""Assembles bitmask from discrete values
|
|
202
|
+
"""Assembles bitmask from discrete values.
|
|
193
203
|
|
|
194
204
|
log_intermediate_node: record / log virtual intermediate (cap-)voltage and
|
|
195
205
|
-current (out) instead of output-voltage and -current
|
|
@@ -204,7 +214,8 @@ class VirtualSourceConfig(ContentModel, title="Config for the virtual Source"):
|
|
|
204
214
|
)
|
|
205
215
|
|
|
206
216
|
def calc_cap_constant_us_per_nF_n28(self) -> int:
|
|
207
|
-
"""Calc constant to convert capacitor-current to Voltage-delta
|
|
217
|
+
"""Calc constant to convert capacitor-current to Voltage-delta.
|
|
218
|
+
|
|
208
219
|
dV[uV] = constant[us/nF] * current[nA] = constant[us*V/nAs] * current[nA]
|
|
209
220
|
"""
|
|
210
221
|
C_cap_uF = max(self.C_intermediate_uF, 0.001)
|
|
@@ -224,7 +235,8 @@ lut_o = Annotated[List[u32], Field(min_length=LUT_SIZE, max_length=LUT_SIZE)]
|
|
|
224
235
|
|
|
225
236
|
|
|
226
237
|
class ConverterPRUConfig(ShpModel):
|
|
227
|
-
"""Map settings-list to internal state-vars struct ConverterConfig
|
|
238
|
+
"""Map settings-list to internal state-vars struct ConverterConfig.
|
|
239
|
+
|
|
228
240
|
NOTE:
|
|
229
241
|
- yaml is based on si-units like nA, mV, ms, uF
|
|
230
242
|
- c-code and py-copy is using nA, uV, ns, nF, fW, raw
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# info:
|
|
2
|
+
# - compendium of all parameters & description
|
|
3
|
+
# - base for neutral fallback values if provided yml is sparse
|
|
4
|
+
# - -> it is encouraged to omit redundant parameters
|
|
5
|
+
---
|
|
6
|
+
- datatype: VirtualSourceConfig
|
|
7
|
+
parameters:
|
|
8
|
+
id: 1000
|
|
9
|
+
name: neutral
|
|
10
|
+
description: Direct feed-through of energy environment with no converter (allows on-off-patters)
|
|
11
|
+
# General Config
|
|
12
|
+
enable_boost: false # if false -> v_intermediate = v_input, output-switch-hysteresis is still usable
|
|
13
|
+
enable_buck: false # if false -> v_output = v_intermediate
|
|
14
|
+
|
|
15
|
+
interval_startup_delay_drain_ms: 0
|
|
16
|
+
|
|
17
|
+
harvester:
|
|
18
|
+
name: mppt_opt # harvester only active if input is "ivcurves"
|
|
19
|
+
|
|
20
|
+
V_input_max_mV: 10000
|
|
21
|
+
I_input_max_mA: 4200
|
|
22
|
+
V_input_drop_mV: 0.0 # simulate input-diode
|
|
23
|
+
R_input_mOhm: 0.0 # resistance only active with disabled boost, range [1 mOhm; 1MOhm]
|
|
24
|
+
|
|
25
|
+
C_intermediate_uF: 0.0 # primary storage-Cap
|
|
26
|
+
V_intermediate_init_mV: 3000 # allow a proper / fast startup
|
|
27
|
+
I_intermediate_leak_nA: 0.0
|
|
28
|
+
|
|
29
|
+
V_intermediate_enable_threshold_mV: 1 # -> target gets connected (hysteresis-combo with next value)
|
|
30
|
+
V_intermediate_disable_threshold_mV: 0 # -> target gets disconnected
|
|
31
|
+
interval_check_thresholds_ms: 0.0 # some BQs check every 64 ms if output should be disconnected
|
|
32
|
+
|
|
33
|
+
V_pwr_good_enable_threshold_mV: 2800 # target is informed by pwr-good on output-pin (hysteresis) -> for intermediate voltage
|
|
34
|
+
V_pwr_good_disable_threshold_mV: 2200
|
|
35
|
+
immediate_pwr_good_signal: true # 1: activate instant schmitt-trigger, 0: stay in interval for checking thresholds
|
|
36
|
+
|
|
37
|
+
C_output_uF: 1.0 # final (always last) stage to compensate undetectable current spikes when enabling power for target
|
|
38
|
+
|
|
39
|
+
# Extra
|
|
40
|
+
V_output_log_gpio_threshold_mV: 1400 # min voltage needed to enable recording changes in gpio-bank
|
|
41
|
+
|
|
42
|
+
# Boost Converter
|
|
43
|
+
V_input_boost_threshold_mV: 0.0 # min input-voltage for the boost converter to work
|
|
44
|
+
V_intermediate_max_mV: 10000 # -> boost converter shuts off
|
|
45
|
+
|
|
46
|
+
LUT_input_efficiency: [
|
|
47
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ], # rows are current -> here a[V=0][:]
|
|
48
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
49
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
50
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
51
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
52
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
53
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
54
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
55
|
+
[ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 ],
|
|
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
|
+
[ 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
|
+
[ 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
|
+
] # input-array[12][12] depending on array[inp_voltage][log(inp_current)], influence of cap-voltage is not implemented
|
|
60
|
+
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: 0 # 2^8 = 256 nA -> array[0] is for inputs < 256 nA
|
|
62
|
+
|
|
63
|
+
# Buck-converter
|
|
64
|
+
V_output_mV: 2400
|
|
65
|
+
V_buck_drop_mV: 0.0 # simulate LDO min voltage differential or output-diode
|
|
66
|
+
|
|
67
|
+
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: 0 # 2^8 = 256 nA -> array[0] is for inputs < 256 nA, see notes on LUT_input for explanation
|
|
69
|
+
|
|
70
|
+
owner: Ingmar
|
|
71
|
+
group: NES Lab
|
|
72
|
+
visible2group: true
|
|
73
|
+
visible2all: true
|
|
74
|
+
created: 2022-12-12 12:12:12
|
|
75
|
+
updated_last: 2022-12-12 12:12:12
|
|
76
|
+
|
|
77
|
+
- datatype: VirtualSourceConfig
|
|
78
|
+
parameters:
|
|
79
|
+
id: 1010
|
|
80
|
+
name: direct
|
|
81
|
+
inherit_from: neutral
|
|
82
|
+
# Note: current input has no influence
|
|
83
|
+
|
|
84
|
+
- datatype: VirtualSourceConfig
|
|
85
|
+
parameters:
|
|
86
|
+
id: 1011
|
|
87
|
+
name: diode+capacitor
|
|
88
|
+
description: Simple Converter based on diode and buffer capacitor
|
|
89
|
+
inherit_from: neutral
|
|
90
|
+
V_input_drop_mV: 300 # simulate input-diode
|
|
91
|
+
C_intermediate_uF: 10 # primary storage-Cap
|
|
92
|
+
|
|
93
|
+
- datatype: VirtualSourceConfig
|
|
94
|
+
parameters:
|
|
95
|
+
id: 1012
|
|
96
|
+
name: dio_cap # simpler naming
|
|
97
|
+
inherit_from: diode+capacitor
|
|
98
|
+
|
|
99
|
+
- datatype: VirtualSourceConfig
|
|
100
|
+
parameters:
|
|
101
|
+
id: 1013
|
|
102
|
+
name: diode+resistor+capacitor
|
|
103
|
+
description: Simple Converter based on diode, current limiting resistor and buffer capacitor
|
|
104
|
+
inherit_from: diode+capacitor
|
|
105
|
+
R_input_mOhm: 10000
|
|
106
|
+
|
|
107
|
+
- datatype: VirtualSourceConfig
|
|
108
|
+
parameters:
|
|
109
|
+
id: 1014
|
|
110
|
+
name: dio_res_cap # simpler naming
|
|
111
|
+
inherit_from: diode+resistor+capacitor
|
|
112
|
+
|
|
113
|
+
- datatype: VirtualSourceConfig
|
|
114
|
+
parameters:
|
|
115
|
+
id: 1020
|
|
116
|
+
name: BQ25504
|
|
117
|
+
description: TI BQ25504 with integrated boost-converter
|
|
118
|
+
inherit_from: neutral # to complete undefined vars
|
|
119
|
+
enable_boost: true # if false -> v_intermediate = v_input, output-switch-hysteresis is still usable
|
|
120
|
+
|
|
121
|
+
harvester:
|
|
122
|
+
name: mppt_bq_solar # harvester only active if input is "ivcurves"
|
|
123
|
+
|
|
124
|
+
V_input_max_mV: 3000
|
|
125
|
+
I_input_max_mA: 100
|
|
126
|
+
|
|
127
|
+
C_intermediate_uF: 22.0 # primary storage-Cap
|
|
128
|
+
V_intermediate_init_mV: 3000 # allow a proper / fast startup
|
|
129
|
+
I_intermediate_leak_nA: 330
|
|
130
|
+
|
|
131
|
+
V_intermediate_enable_threshold_mV: 2600 # -> target gets connected (hysteresis-combo with next value)
|
|
132
|
+
V_intermediate_disable_threshold_mV: 2300 # -> target gets disconnected
|
|
133
|
+
interval_check_thresholds_ms: 64.0 # some BQs check every 64 ms if output should be disconnected
|
|
134
|
+
|
|
135
|
+
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: 2400
|
|
137
|
+
immediate_pwr_good_signal: false # 1: activate instant schmitt-trigger, 0: stay in interval for checking thresholds
|
|
138
|
+
|
|
139
|
+
# Boost Converter
|
|
140
|
+
V_input_boost_threshold_mV: 130 # min input-voltage for the boost converter to work
|
|
141
|
+
V_intermediate_max_mV: 3600 # -> boost converter shuts off
|
|
142
|
+
|
|
143
|
+
LUT_input_efficiency: [
|
|
144
|
+
# <8uA 8uA 16uA 32uA 64uA 128uA 256uA 512uA 1mA 2mA 4mA >8mA
|
|
145
|
+
[ 0.01, 0.01, 0.02, 0.05, 0.10, 0.15, 0.15, 0.20, 0.25, 0.30, 0.30, 0.35 ], # < 128 mV
|
|
146
|
+
[ 0.10, 0.20, 0.30, 0.40, 0.50, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61 ], # > 128 mV, ~200
|
|
147
|
+
[ 0.20, 0.40, 0.50, 0.60, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72 ], # > 256 mV, ~320
|
|
148
|
+
[ 0.35, 0.55, 0.65, 0.71, 0.73, 0.74, 0.75, 0.75, 0.76, 0.77, 0.77, 0.78 ], # > 384 mV, ~450
|
|
149
|
+
[ 0.45, 0.65, 0.70, 0.73, 0.75, 0.77, 0.78, 0.79, 0.80, 0.81, 0.81, 0.82 ], # > 512 mV, ~570
|
|
150
|
+
[ 0.50, 0.70, 0.74, 0.76, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.83, 0.84 ], # > 640 mV
|
|
151
|
+
[ 0.52, 0.73, 0.76, 0.78, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.85, 0.86 ], # > 768 mV
|
|
152
|
+
[ 0.53, 0.75, 0.77, 0.79, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.86, 0.87 ], # > 896 mV
|
|
153
|
+
[ 0.55, 0.77, 0.78, 0.80, 0.82, 0.83, 0.85, 0.86, 0.87, 0.87, 0.87, 0.88 ], # > 1024 mV
|
|
154
|
+
[ 0.56, 0.78, 0.79, 0.81, 0.83, 0.85, 0.87, 0.88, 0.88, 0.88, 0.88, 0.89 ], # > 1152 mV
|
|
155
|
+
[ 0.58, 0.79, 0.80, 0.82, 0.84, 0.86, 0.88, 0.89, 0.89, 0.89, 0.89, 0.90 ], # > 1280 mV
|
|
156
|
+
[ 0.60, 0.80, 0.81, 0.83, 0.85, 0.87, 0.89, 0.90, 0.90, 0.90, 0.90, 0.90 ], # > 1408 mV
|
|
157
|
+
] # input-array[12][12] depending on array[inp_voltage][log(inp_current)], influence of cap-voltage is not implemented
|
|
158
|
+
LUT_input_V_min_log2_uV: 17 # example: 2^7 = 128 uV -> array[0] is for inputs < 128 uV
|
|
159
|
+
LUT_input_I_min_log2_nA: 13 # example: 2^8 = 256 nA -> array[0] is for inputs < 256 nA
|
|
160
|
+
|
|
161
|
+
- datatype: VirtualSourceConfig
|
|
162
|
+
parameters:
|
|
163
|
+
id: 1021
|
|
164
|
+
name: BQ25504s # Version with Schmitt-Trigger
|
|
165
|
+
description: TI BQ25504 with Schmitt-Trigger for a faster power-good-signal
|
|
166
|
+
inherit_from: BQ25504
|
|
167
|
+
immediate_pwr_good_signal: true
|
|
168
|
+
|
|
169
|
+
- datatype: VirtualSourceConfig
|
|
170
|
+
parameters:
|
|
171
|
+
id: 1022
|
|
172
|
+
name: BQ25504-Schmitt
|
|
173
|
+
inherit_from: BQ25504s
|
|
174
|
+
|
|
175
|
+
- datatype: VirtualSourceConfig
|
|
176
|
+
parameters:
|
|
177
|
+
id: 1030
|
|
178
|
+
name: BQ25570
|
|
179
|
+
description: TI BQ25570 with integrated boost- & buck-converter
|
|
180
|
+
inherit_from: BQ25504 # inherit Input-LUT that is similar enough
|
|
181
|
+
enable_boost: true # if false -> v_intermediate = v_input, output-switch-hysteresis is still usable
|
|
182
|
+
enable_buck: true # if false -> v_output = v_intermediate
|
|
183
|
+
|
|
184
|
+
V_input_max_mV: 5100
|
|
185
|
+
I_input_max_mA: 100
|
|
186
|
+
|
|
187
|
+
C_intermediate_uF: 33.0 # primary storage-Cap
|
|
188
|
+
V_intermediate_init_mV: 3400 # allow a proper / fast startup
|
|
189
|
+
I_intermediate_leak_nA: 0.0
|
|
190
|
+
|
|
191
|
+
V_intermediate_enable_threshold_mV: 3000 # -> target gets connected (hysteresis-combo with next value)
|
|
192
|
+
V_intermediate_disable_threshold_mV: 2400 # -> target gets disconnected
|
|
193
|
+
interval_check_thresholds_ms: 64.0 # some BQs check every 64 ms if output should be disconnected
|
|
194
|
+
|
|
195
|
+
V_pwr_good_enable_threshold_mV: 3000 # target is informed by pwr-good on output-pin (hysteresis) -> for intermediate voltage
|
|
196
|
+
V_pwr_good_disable_threshold_mV: 2500
|
|
197
|
+
immediate_pwr_good_signal: false # 1: activate instant schmitt-trigger, 0: stay in interval for checking thresholds
|
|
198
|
+
|
|
199
|
+
C_output_uF: 1.0 # final (always last) stage to compensate undetectable current spikes when enabling power for target
|
|
200
|
+
|
|
201
|
+
# Boost Converter
|
|
202
|
+
V_input_boost_threshold_mV: 100.0 # min input-voltage for the boost converter to work
|
|
203
|
+
V_intermediate_max_mV: 5500 # -> boost converter shuts off
|
|
204
|
+
|
|
205
|
+
# Buck Converter
|
|
206
|
+
V_output_mV: 2200
|
|
207
|
+
V_buck_drop_mV: 200.0 # simulate LDO min voltage differential or output-diode
|
|
208
|
+
|
|
209
|
+
# <1u 1u 2u 4u 8u 16u 32u 64u 128u 256u 512u >1m
|
|
210
|
+
LUT_output_efficiency: [ 0.40, 0.50, 0.60, 0.73, 0.82, 0.86, 0.88, 0.90, 0.91, 0.92, 0.93, 0.92] # array[12] depending on output_current
|
|
211
|
+
LUT_output_I_min_log2_nA: 10 # example: 2^8 = 256 nA -> array[0] is for inputs < 256 nA, see notes on LUT_input for explanation
|
|
212
|
+
|
|
213
|
+
- datatype: VirtualSourceConfig
|
|
214
|
+
parameters:
|
|
215
|
+
id: 1031
|
|
216
|
+
name: BQ25570s
|
|
217
|
+
description: TI BQ25570 with Schmitt-Trigger for a faster power-good-signal
|
|
218
|
+
inherit_from: BQ25570
|
|
219
|
+
immediate_pwr_good_signal: true
|
|
220
|
+
|
|
221
|
+
- datatype: VirtualSourceConfig
|
|
222
|
+
parameters:
|
|
223
|
+
id: 1032
|
|
224
|
+
name: BQ25570-Schmitt
|
|
225
|
+
inherit_from: BQ25570s
|
|
226
|
+
- datatype: VirtualSourceConfig
|
|
227
|
+
parameters:
|
|
228
|
+
id: 1033
|
|
229
|
+
name: default
|
|
230
|
+
inherit_from: BQ25570s
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
"""Module for experiment related data-models.
|
|
2
|
+
|
|
3
|
+
These models import externally from: /base, /content, /testbed.
|
|
4
|
+
"""
|
|
5
|
+
|
|
2
6
|
from .experiment import Experiment
|
|
3
7
|
from .observer_features import GpioActuation
|
|
4
8
|
from .observer_features import GpioEvent
|
|
@@ -8,8 +12,6 @@ from .observer_features import PowerTracing
|
|
|
8
12
|
from .observer_features import SystemLogging
|
|
9
13
|
from .target_config import TargetConfig
|
|
10
14
|
|
|
11
|
-
# these models import externally from: /base, /content, /testbed
|
|
12
|
-
|
|
13
15
|
__all__ = [
|
|
14
16
|
"Experiment",
|
|
15
17
|
"TargetConfig",
|
|
@@ -21,5 +23,4 @@ __all__ = [
|
|
|
21
23
|
"SystemLogging",
|
|
22
24
|
# Enums
|
|
23
25
|
"GpioLevel",
|
|
24
|
-
"TargetPort",
|
|
25
26
|
]
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Config for testbed experiments."""
|
|
2
|
+
|
|
1
3
|
from datetime import datetime
|
|
2
4
|
from datetime import timedelta
|
|
3
5
|
from typing import List
|
|
@@ -22,12 +24,10 @@ from .target_config import TargetConfig
|
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class Experiment(ShpModel, title="Config of an Experiment"):
|
|
25
|
-
"""
|
|
26
|
-
emulating Energy Environments for Target Nodes
|
|
27
|
-
"""
|
|
27
|
+
"""Config for experiments on the testbed emulating energy environments for target nodes."""
|
|
28
28
|
|
|
29
29
|
# General Properties
|
|
30
|
-
# id: UUID4 ... # TODO db-migration - temp fix for documentation
|
|
30
|
+
# id: UUID4 ... # TODO: db-migration - temp fix for documentation
|
|
31
31
|
id: Union[UUID4, int] = Field(default_factory=uuid4)
|
|
32
32
|
# ⤷ TODO: automatic ID is problematic for identification by hash
|
|
33
33
|
|
|
@@ -90,7 +90,7 @@ class Experiment(ShpModel, title="Config of an Experiment"):
|
|
|
90
90
|
obs_ids = [testbed.get_observer(_id).id for _id in target_ids]
|
|
91
91
|
if len(target_ids) > len(set(obs_ids)):
|
|
92
92
|
raise ValueError(
|
|
93
|
-
"Observer used more than once in Experiment -> only 1 target per observer!"
|
|
93
|
+
"Observer is used more than once in Experiment -> only 1 target per observer!"
|
|
94
94
|
)
|
|
95
95
|
|
|
96
96
|
def get_target_ids(self) -> list:
|
|
@@ -101,4 +101,5 @@ class Experiment(ShpModel, title="Config of an Experiment"):
|
|
|
101
101
|
if target_id in _config.target_IDs:
|
|
102
102
|
return _config
|
|
103
103
|
# gets already caught in target_config - but keep:
|
|
104
|
-
|
|
104
|
+
msg = f"Target-ID {target_id} was not found in Experiment '{self.name}'"
|
|
105
|
+
raise ValueError(msg)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Configs for observer features like gpio- & power-tracing."""
|
|
2
|
+
|
|
1
3
|
from datetime import timedelta
|
|
2
4
|
from enum import Enum
|
|
3
5
|
from typing import List
|
|
@@ -15,7 +17,8 @@ from ..testbed.gpio import GPIO
|
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class PowerTracing(ShpModel, title="Config for Power-Tracing"):
|
|
18
|
-
"""Configuration for recording the Power-Consumption of the Target Nodes
|
|
20
|
+
"""Configuration for recording the Power-Consumption of the Target Nodes.
|
|
21
|
+
|
|
19
22
|
TODO: postprocessing not implemented ATM
|
|
20
23
|
"""
|
|
21
24
|
|
|
@@ -45,12 +48,13 @@ class PowerTracing(ShpModel, title="Config for Power-Tracing"):
|
|
|
45
48
|
if not self.calculate_power and discard_all:
|
|
46
49
|
raise ValueError("Error in config -> tracing enabled, but output gets discarded")
|
|
47
50
|
if self.calculate_power:
|
|
48
|
-
raise
|
|
51
|
+
raise NotImplementedError("postprocessing not implemented ATM")
|
|
49
52
|
return self
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
class GpioTracing(ShpModel, title="Config for GPIO-Tracing"):
|
|
53
|
-
"""Configuration for recording the GPIO-Output of the Target Nodes
|
|
56
|
+
"""Configuration for recording the GPIO-Output of the Target Nodes.
|
|
57
|
+
|
|
54
58
|
TODO: postprocessing not implemented ATM
|
|
55
59
|
"""
|
|
56
60
|
|
|
@@ -84,13 +88,15 @@ class GpioTracing(ShpModel, title="Config for GPIO-Tracing"):
|
|
|
84
88
|
|
|
85
89
|
|
|
86
90
|
class GpioLevel(str, Enum):
|
|
91
|
+
"""Options for setting the gpio-level or state."""
|
|
92
|
+
|
|
87
93
|
low = "L"
|
|
88
94
|
high = "H"
|
|
89
95
|
toggle = "X" # TODO: not the smartest decision for writing a converter
|
|
90
96
|
|
|
91
97
|
|
|
92
98
|
class GpioEvent(ShpModel, title="Config for a GPIO-Event"):
|
|
93
|
-
"""Configuration for a single GPIO-Event (Actuation)"""
|
|
99
|
+
"""Configuration for a single GPIO-Event (Actuation)."""
|
|
94
100
|
|
|
95
101
|
delay: PositiveFloat
|
|
96
102
|
# ⤷ from start_time
|
|
@@ -104,7 +110,8 @@ class GpioEvent(ShpModel, title="Config for a GPIO-Event"):
|
|
|
104
110
|
@model_validator(mode="after")
|
|
105
111
|
def post_validation(self) -> Self:
|
|
106
112
|
if not self.gpio.user_controllable():
|
|
107
|
-
|
|
113
|
+
msg = f"GPIO '{self.gpio.name}' in actuation-event not controllable by user"
|
|
114
|
+
raise ValueError(msg)
|
|
108
115
|
return self
|
|
109
116
|
|
|
110
117
|
def get_events(self) -> np.ndarray:
|
|
@@ -113,7 +120,7 @@ class GpioEvent(ShpModel, title="Config for a GPIO-Event"):
|
|
|
113
120
|
|
|
114
121
|
|
|
115
122
|
class GpioActuation(ShpModel, title="Config for GPIO-Actuation"):
|
|
116
|
-
"""Configuration for a GPIO-Actuation-Sequence"""
|
|
123
|
+
"""Configuration for a GPIO-Actuation-Sequence."""
|
|
117
124
|
|
|
118
125
|
# TODO: not implemented ATM - decide if pru control sys-gpio or
|
|
119
126
|
# TODO: not implemented ATM - reverses pru-gpio (preferred if possible)
|
|
@@ -125,7 +132,7 @@ class GpioActuation(ShpModel, title="Config for GPIO-Actuation"):
|
|
|
125
132
|
|
|
126
133
|
|
|
127
134
|
class SystemLogging(ShpModel, title="Config for System-Logging"):
|
|
128
|
-
"""Configuration for recording Debug-Output of the Observers System-Services"""
|
|
135
|
+
"""Configuration for recording Debug-Output of the Observers System-Services."""
|
|
129
136
|
|
|
130
137
|
dmesg: bool = True
|
|
131
138
|
ptp: bool = True
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Configuration related to Target Nodes (DuT)."""
|
|
2
|
+
|
|
1
3
|
from typing import List
|
|
2
4
|
from typing import Optional
|
|
3
5
|
|
|
@@ -19,7 +21,7 @@ from .observer_features import PowerTracing
|
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
class TargetConfig(ShpModel, title="Target Config"):
|
|
22
|
-
"""Configuration
|
|
24
|
+
"""Configuration related to Target Nodes (DuT)."""
|
|
23
25
|
|
|
24
26
|
target_IDs: Annotated[List[IdInt], Field(min_length=1, max_length=128)]
|
|
25
27
|
custom_IDs: Optional[Annotated[List[IdInt16], Field(min_length=1, max_length=128)]] = None
|
|
@@ -44,7 +46,8 @@ class TargetConfig(ShpModel, title="Target Config"):
|
|
|
44
46
|
@model_validator(mode="after")
|
|
45
47
|
def post_validation(self) -> Self:
|
|
46
48
|
if not self.energy_env.valid:
|
|
47
|
-
|
|
49
|
+
msg = f"EnergyEnv '{self.energy_env.name}' for target must be valid"
|
|
50
|
+
raise ValueError(msg)
|
|
48
51
|
for _id in self.target_IDs:
|
|
49
52
|
target = Target(id=_id)
|
|
50
53
|
for mcu_num in [1, 2]:
|
|
@@ -56,24 +59,25 @@ class TargetConfig(ShpModel, title="Target Config"):
|
|
|
56
59
|
fw_def = Firmware(name=tgt_mcu.fw_name_default)
|
|
57
60
|
# ⤷ this will raise if default is faulty
|
|
58
61
|
if tgt_mcu.id != fw_def.mcu.id:
|
|
59
|
-
|
|
62
|
+
msg = (
|
|
60
63
|
f"Default-Firmware for MCU{mcu_num} of Target-ID '{target.id}' "
|
|
61
64
|
f"(={fw_def.mcu.name}) "
|
|
62
65
|
f"is incompatible (={tgt_mcu.name})"
|
|
63
66
|
)
|
|
67
|
+
raise ValueError(msg)
|
|
64
68
|
if has_fw and has_mcu and val_fw.mcu.id != tgt_mcu.id:
|
|
65
|
-
|
|
69
|
+
msg = (
|
|
66
70
|
f"Firmware{mcu_num} for MCU of Target-ID '{target.id}' "
|
|
67
71
|
f"(={val_fw.mcu.name}) "
|
|
68
72
|
f"is incompatible (={tgt_mcu.name})"
|
|
69
73
|
)
|
|
74
|
+
raise ValueError(msg)
|
|
70
75
|
|
|
71
76
|
c_ids = self.custom_IDs
|
|
72
77
|
t_ids = self.target_IDs
|
|
73
78
|
if c_ids is not None and (len(set(c_ids)) < len(set(t_ids))):
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)
|
|
79
|
+
msg = f"Provided custom IDs {c_ids} not enough to cover target range {t_ids}"
|
|
80
|
+
raise ValueError(msg)
|
|
77
81
|
# TODO: if custom ids present, firmware must be ELF
|
|
78
82
|
return self
|
|
79
83
|
|