shepherd-core 2024.8.1__py3-none-any.whl → 2024.8.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shepherd_core/data_models/content/virtual_source_fixture.yaml +1 -1
- shepherd_core/version.py +1 -1
- shepherd_core/vsource/__init__.py +10 -0
- shepherd_core/vsource/target_model.py +62 -0
- shepherd_core/vsource/virtual_harvester_simulation.py +71 -0
- shepherd_core/vsource/virtual_source_simulation.py +78 -0
- {shepherd_core-2024.8.1.dist-info → shepherd_core-2024.8.2.dist-info}/METADATA +1 -1
- {shepherd_core-2024.8.1.dist-info → shepherd_core-2024.8.2.dist-info}/RECORD +11 -8
- {shepherd_core-2024.8.1.dist-info → shepherd_core-2024.8.2.dist-info}/WHEEL +0 -0
- {shepherd_core-2024.8.1.dist-info → shepherd_core-2024.8.2.dist-info}/top_level.txt +0 -0
- {shepherd_core-2024.8.1.dist-info → shepherd_core-2024.8.2.dist-info}/zip-safe +0 -0
shepherd_core/version.py
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
"""Simulation model of the virtual source."""
|
|
2
2
|
|
|
3
|
+
from .target_model import ConstantCurrentTarget
|
|
4
|
+
from .target_model import ConstantPowerTarget
|
|
5
|
+
from .target_model import ResistiveTarget
|
|
3
6
|
from .virtual_converter_model import PruCalibration
|
|
4
7
|
from .virtual_converter_model import VirtualConverterModel
|
|
5
8
|
from .virtual_harvester_model import VirtualHarvesterModel
|
|
9
|
+
from .virtual_harvester_simulation import simulate_harvester
|
|
6
10
|
from .virtual_source_model import VirtualSourceModel
|
|
11
|
+
from .virtual_source_simulation import simulate_source
|
|
7
12
|
|
|
8
13
|
__all__ = [
|
|
9
14
|
"PruCalibration",
|
|
10
15
|
"VirtualConverterModel",
|
|
11
16
|
"VirtualHarvesterModel",
|
|
12
17
|
"VirtualSourceModel",
|
|
18
|
+
"simulate_harvester",
|
|
19
|
+
"simulate_source",
|
|
20
|
+
"ResistiveTarget",
|
|
21
|
+
"ConstantCurrentTarget",
|
|
22
|
+
"ConstantPowerTarget",
|
|
13
23
|
]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Virtual targets with different characteristics.
|
|
2
|
+
|
|
3
|
+
TODO: add more targets
|
|
4
|
+
- diode
|
|
5
|
+
- constant power
|
|
6
|
+
- constant current
|
|
7
|
+
- msp430 (const I)
|
|
8
|
+
- nRF (constant power due to regulator)
|
|
9
|
+
- riotee
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from abc import ABC
|
|
13
|
+
from abc import abstractmethod
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TargetABC(ABC):
|
|
17
|
+
"""Abstract base class for all targets."""
|
|
18
|
+
|
|
19
|
+
@abstractmethod
|
|
20
|
+
def step(self, voltage_uV: int, *, pwr_good: bool) -> float:
|
|
21
|
+
"""Calculate one time step and return drawn current in nA."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ResistiveTarget(TargetABC):
|
|
25
|
+
"""Predictable target for matching the real world."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, resistance_Ohm: float, *, controlled: bool = False) -> None:
|
|
28
|
+
if resistance_Ohm <= 1e-3:
|
|
29
|
+
raise ValueError("Resistance must be greater than 1 mOhm.")
|
|
30
|
+
self.r_kOhm = 1e-3 * resistance_Ohm
|
|
31
|
+
self.ctrl = controlled
|
|
32
|
+
|
|
33
|
+
def step(self, voltage_uV: int, *, pwr_good: bool) -> float:
|
|
34
|
+
if pwr_good or not self.ctrl:
|
|
35
|
+
return voltage_uV / self.r_kOhm # = nA
|
|
36
|
+
return 0
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ConstantCurrentTarget(TargetABC):
|
|
40
|
+
"""Recreate simple MCU without integrated regulator."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, i_active_A: float, i_sleep_A: float = 0) -> None:
|
|
43
|
+
if i_active_A <= 0 or i_sleep_A <= 0:
|
|
44
|
+
raise ValueError("Current must be greater than 0.")
|
|
45
|
+
self.i_active_nA = 1e9 * i_active_A
|
|
46
|
+
self.i_sleep_nA = 1e9 * i_sleep_A
|
|
47
|
+
|
|
48
|
+
def step(self, voltage_uV: int, *, pwr_good: bool) -> float: # noqa: ARG002
|
|
49
|
+
return self.i_active_nA if pwr_good else self.i_sleep_nA
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ConstantPowerTarget(TargetABC):
|
|
53
|
+
"""Recreate MCU with integrated regulator."""
|
|
54
|
+
|
|
55
|
+
def __init__(self, p_active_W: float, p_sleep_W: float = 0) -> None:
|
|
56
|
+
if p_active_W <= 0 or p_sleep_W <= 0:
|
|
57
|
+
raise ValueError("Power must be greater than 0.")
|
|
58
|
+
self.p_active_fW = 1e15 * p_active_W
|
|
59
|
+
self.p_sleep_fW = 1e15 * p_sleep_W
|
|
60
|
+
|
|
61
|
+
def step(self, voltage_uV: int, *, pwr_good: bool) -> float:
|
|
62
|
+
return (self.p_active_fW if pwr_good else self.p_sleep_fW) / voltage_uV # = nA
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Simulate behavior of virtual harvester algorithms.
|
|
2
|
+
|
|
3
|
+
The simulation recreates an observer-cape and the virtual harvester
|
|
4
|
+
- input = hdf5-file with an ivcurve
|
|
5
|
+
- output = optional as hdf5-file
|
|
6
|
+
|
|
7
|
+
The output file can be analyzed and plotted with shepherds tool suite.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from contextlib import ExitStack
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Optional
|
|
13
|
+
|
|
14
|
+
from tqdm import tqdm
|
|
15
|
+
|
|
16
|
+
from .. import CalibrationHarvester
|
|
17
|
+
from .. import Reader
|
|
18
|
+
from .. import Writer
|
|
19
|
+
from ..data_models.content.virtual_harvester import HarvesterPRUConfig
|
|
20
|
+
from ..data_models.content.virtual_harvester import VirtualHarvesterConfig
|
|
21
|
+
from .virtual_harvester_model import VirtualHarvesterModel
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def simulate_harvester(
|
|
25
|
+
config: VirtualHarvesterConfig, path_input: Path, path_output: Optional[Path] = None
|
|
26
|
+
) -> float:
|
|
27
|
+
"""Simulate behavior of virtual harvester algorithms.
|
|
28
|
+
|
|
29
|
+
Fn return the harvested energy.
|
|
30
|
+
"""
|
|
31
|
+
stack = ExitStack()
|
|
32
|
+
file_inp = Reader(path_input, verbose=False)
|
|
33
|
+
stack.enter_context(file_inp)
|
|
34
|
+
cal_inp = file_inp.get_calibration_data()
|
|
35
|
+
|
|
36
|
+
if path_output:
|
|
37
|
+
cal_hrv = CalibrationHarvester()
|
|
38
|
+
file_out = Writer(
|
|
39
|
+
path_output, cal_data=cal_hrv, mode="harvester", verbose=False, force_overwrite=True
|
|
40
|
+
)
|
|
41
|
+
stack.enter_context(file_out)
|
|
42
|
+
cal_out = file_out.get_calibration_data()
|
|
43
|
+
file_out.store_hostname("hrv_sim_" + config.name)
|
|
44
|
+
|
|
45
|
+
hrv_pru = HarvesterPRUConfig.from_vhrv(
|
|
46
|
+
config,
|
|
47
|
+
for_emu=True,
|
|
48
|
+
dtype_in=file_inp.get_datatype(),
|
|
49
|
+
window_size=file_inp.get_window_samples(),
|
|
50
|
+
)
|
|
51
|
+
hrv = VirtualHarvesterModel(hrv_pru)
|
|
52
|
+
e_out_Ws = 0.0
|
|
53
|
+
|
|
54
|
+
for _t, v_inp, i_inp in tqdm(
|
|
55
|
+
file_inp.read_buffers(is_raw=True), total=file_inp.buffers_n, desc="Buffers", leave=False
|
|
56
|
+
):
|
|
57
|
+
v_uV = cal_inp.voltage.raw_to_si(v_inp) * 1e6
|
|
58
|
+
i_nA = cal_inp.current.raw_to_si(i_inp) * 1e9
|
|
59
|
+
length = min(v_uV.size, i_nA.size)
|
|
60
|
+
for _n in range(length):
|
|
61
|
+
v_uV[_n], i_nA[_n] = hrv.ivcurve_sample(
|
|
62
|
+
_voltage_uV=int(v_uV[_n]), _current_nA=int(i_nA[_n])
|
|
63
|
+
)
|
|
64
|
+
e_out_Ws += (v_uV * i_nA).sum() * 1e-15 * file_inp.sample_interval_s
|
|
65
|
+
if path_output:
|
|
66
|
+
v_out = cal_out.voltage.si_to_raw(v_uV / 1e6)
|
|
67
|
+
i_out = cal_out.current.si_to_raw(i_nA / 1e9)
|
|
68
|
+
file_out.append_iv_data_raw(_t, v_out, i_out)
|
|
69
|
+
|
|
70
|
+
stack.close()
|
|
71
|
+
return e_out_Ws
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Simulate behavior of virtual source algorithms.
|
|
2
|
+
|
|
3
|
+
The simulation recreates an observer-cape, the virtual Source and a virtual target
|
|
4
|
+
- input = hdf5-file with a harvest-recording
|
|
5
|
+
- output = optional as hdf5-file
|
|
6
|
+
|
|
7
|
+
The output file can be analyzed and plotted with shepherds tool suite.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from contextlib import ExitStack
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Optional
|
|
13
|
+
|
|
14
|
+
from tqdm import tqdm
|
|
15
|
+
|
|
16
|
+
from .. import CalibrationEmulator
|
|
17
|
+
from .. import Reader
|
|
18
|
+
from .. import Writer
|
|
19
|
+
from ..data_models import VirtualSourceConfig
|
|
20
|
+
from . import VirtualSourceModel
|
|
21
|
+
from .target_model import TargetABC
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def simulate_source(
|
|
25
|
+
config: VirtualSourceConfig,
|
|
26
|
+
target: TargetABC,
|
|
27
|
+
path_input: Path,
|
|
28
|
+
path_output: Optional[Path] = None,
|
|
29
|
+
) -> float:
|
|
30
|
+
"""Simulate behavior of virtual source algorithms.
|
|
31
|
+
|
|
32
|
+
FN returns the consumed energy of the target.
|
|
33
|
+
"""
|
|
34
|
+
stack = ExitStack()
|
|
35
|
+
file_inp = Reader(path_input, verbose=False)
|
|
36
|
+
stack.enter_context(file_inp)
|
|
37
|
+
cal_emu = CalibrationEmulator()
|
|
38
|
+
cal_inp = file_inp.get_calibration_data()
|
|
39
|
+
|
|
40
|
+
if path_output:
|
|
41
|
+
file_out = Writer(
|
|
42
|
+
path_output, cal_data=cal_emu, mode="emulator", verbose=False, force_overwrite=True
|
|
43
|
+
)
|
|
44
|
+
stack.enter_context(file_out)
|
|
45
|
+
file_out.store_hostname("emu_sim_" + config.name)
|
|
46
|
+
file_out.store_config(config.model_dump())
|
|
47
|
+
cal_out = file_out.get_calibration_data()
|
|
48
|
+
|
|
49
|
+
src = VirtualSourceModel(
|
|
50
|
+
config, cal_emu, log_intermediate=False, window_size=file_inp.get_window_samples()
|
|
51
|
+
)
|
|
52
|
+
i_out_nA = 0
|
|
53
|
+
e_out_Ws = 0.0
|
|
54
|
+
|
|
55
|
+
for _t, v_inp, i_inp in tqdm(
|
|
56
|
+
file_inp.read_buffers(is_raw=True), total=file_inp.buffers_n, desc="Buffers", leave=False
|
|
57
|
+
):
|
|
58
|
+
v_uV = 1e6 * cal_inp.voltage.raw_to_si(v_inp)
|
|
59
|
+
i_nA = 1e9 * cal_inp.current.raw_to_si(i_inp)
|
|
60
|
+
|
|
61
|
+
for _n in range(len(_t)):
|
|
62
|
+
v_uV[_n] = src.iterate_sampling(
|
|
63
|
+
V_inp_uV=int(v_uV[_n]),
|
|
64
|
+
I_inp_nA=int(i_nA[_n]),
|
|
65
|
+
I_out_nA=i_out_nA,
|
|
66
|
+
)
|
|
67
|
+
i_out_nA = target.step(int(v_uV[_n]), pwr_good=src.cnv.get_power_good())
|
|
68
|
+
i_nA[_n] = i_out_nA
|
|
69
|
+
# TODO: src.cnv.get_I_mod_out_nA() has more internal drains
|
|
70
|
+
|
|
71
|
+
e_out_Ws += (v_uV * i_nA).sum() * 1e-15 * file_inp.sample_interval_s
|
|
72
|
+
if path_output:
|
|
73
|
+
v_out = cal_out.voltage.si_to_raw(1e-6 * v_uV)
|
|
74
|
+
i_out = cal_out.current.si_to_raw(1e-9 * i_nA)
|
|
75
|
+
file_out.append_iv_data_raw(_t, v_out, i_out)
|
|
76
|
+
|
|
77
|
+
stack.close()
|
|
78
|
+
return e_out_Ws
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: shepherd_core
|
|
3
|
-
Version: 2024.8.
|
|
3
|
+
Version: 2024.8.2
|
|
4
4
|
Summary: Programming- and CLI-Interface for the h5-dataformat of the Shepherd-Testbed
|
|
5
5
|
Author-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
|
|
6
6
|
Maintainer-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
|
|
@@ -3,7 +3,7 @@ shepherd_core/calibration_hw_def.py,sha256=_nMzgNzSnYyqcLnVCGd4tfA2e0avUXbccjmNp
|
|
|
3
3
|
shepherd_core/commons.py,sha256=vymKXWcy_1bz7ChzzEATUkJ4p3czCzjIdsSehVjJOY8,218
|
|
4
4
|
shepherd_core/logger.py,sha256=4Q4hTI-nccOZ1_A68fo4UEctfu3pJx3IeHfa9VuDDEo,1804
|
|
5
5
|
shepherd_core/reader.py,sha256=xpzwt1JjubNat0PNwdzmBJltLPOmvCyQGwcC-bq83ZI,27052
|
|
6
|
-
shepherd_core/version.py,sha256=
|
|
6
|
+
shepherd_core/version.py,sha256=2UChDgJ4n71vSZH0_L2ArDetMFRZd-5aZO5ppY2Yhrg,75
|
|
7
7
|
shepherd_core/writer.py,sha256=t53fXkYUWHhYnOFnHCoMWwUADkgYydy9Dg66PiqPa68,14946
|
|
8
8
|
shepherd_core/data_models/__init__.py,sha256=IVjKbT2Ilz5bev325EvAuuhd9LfQgQ1u7qKo6dhVA2k,1866
|
|
9
9
|
shepherd_core/data_models/readme.md,sha256=1bdfEypY_0NMhXLxOPRnLAsFca0HuHdq7_01yEWxvUs,2470
|
|
@@ -24,7 +24,7 @@ shepherd_core/data_models/content/firmware_datatype.py,sha256=XPU9LOoT3h5qFOlE8W
|
|
|
24
24
|
shepherd_core/data_models/content/virtual_harvester.py,sha256=52HNac5k_GBCAhT2jBgu8oIqnvwMN3WMVmsAJrrxVRo,9678
|
|
25
25
|
shepherd_core/data_models/content/virtual_harvester_fixture.yaml,sha256=1u-V9RvFhbU74wEUv-BMQugh7OdzBE1SvhVe1v0DN-8,4251
|
|
26
26
|
shepherd_core/data_models/content/virtual_source.py,sha256=2ebNI1CvZgcfY5nz9P9p-Vr26E9l9bli9YeEd6_7yBY,14364
|
|
27
|
-
shepherd_core/data_models/content/virtual_source_fixture.yaml,sha256=
|
|
27
|
+
shepherd_core/data_models/content/virtual_source_fixture.yaml,sha256=8Y1HwGRUPKTA6xwI74MFXFYUT018aI7WRlkPIhODwcQ,10525
|
|
28
28
|
shepherd_core/data_models/experiment/__init__.py,sha256=9TE9_aSnCNRhagsIWLTE8XkyjyMGB7kEGdswl-296v0,645
|
|
29
29
|
shepherd_core/data_models/experiment/experiment.py,sha256=wnn6T3czuh4rz6OSYtMltCTbRpPX55TLVAtQcKO7Uhg,4044
|
|
30
30
|
shepherd_core/data_models/experiment/observer_features.py,sha256=qxnb7anuQz9ZW5IUlPdUXYPIl5U7O9uXkJqZtMnAb0Y,5156
|
|
@@ -66,12 +66,15 @@ shepherd_core/testbed_client/client_abc_fix.py,sha256=BsSkpvJHURRejlS-YPF1f6QRPC
|
|
|
66
66
|
shepherd_core/testbed_client/client_web.py,sha256=iMh5T91152uugbFsqr2vvxLser0KIo5g426dp_6QWUE,5774
|
|
67
67
|
shepherd_core/testbed_client/fixtures.py,sha256=4Uk583R4r6I5IB78HxOn-9UNH3sbFha7OPEdcSXvMCU,9939
|
|
68
68
|
shepherd_core/testbed_client/user_model.py,sha256=5M3vWkAGBwdGDUYAanAjrZwpzMBlh3XLOVvNYWiLmms,2107
|
|
69
|
-
shepherd_core/vsource/__init__.py,sha256=
|
|
69
|
+
shepherd_core/vsource/__init__.py,sha256=GVB-FwuO2mvM15mGX9EQC1lbUmHMLmUEFGYkGmIngPM,771
|
|
70
|
+
shepherd_core/vsource/target_model.py,sha256=J_8-MHs_gIMcE3ZYTgoFsrO6VShR6SFJ5CA3lwuPC2U,2049
|
|
70
71
|
shepherd_core/vsource/virtual_converter_model.py,sha256=sQkJSj-7CVabHvXqk6C3cbLmztSSsdrSU3WgYr4h30E,11067
|
|
71
72
|
shepherd_core/vsource/virtual_harvester_model.py,sha256=ROR8vtKeM2WTnogV68TKBOu0zRVwOwQj_q67hW_qtpQ,8297
|
|
73
|
+
shepherd_core/vsource/virtual_harvester_simulation.py,sha256=EiBrvmc6D2N7Z0DqFBWPdRJK6hR8Q3iQaj7EYP9pLA0,2405
|
|
72
74
|
shepherd_core/vsource/virtual_source_model.py,sha256=fjN8myTY3I_LpikF_aGAcxes3RGu1GP23P7XKC_UIyA,2737
|
|
73
|
-
shepherd_core
|
|
74
|
-
shepherd_core-2024.8.
|
|
75
|
-
shepherd_core-2024.8.
|
|
76
|
-
shepherd_core-2024.8.
|
|
77
|
-
shepherd_core-2024.8.
|
|
75
|
+
shepherd_core/vsource/virtual_source_simulation.py,sha256=swopkXe60LozBkp_-e1WCla-eVCG2klTFB5bLAUj51I,2528
|
|
76
|
+
shepherd_core-2024.8.2.dist-info/METADATA,sha256=oDQiB1H6NM3zW-SuQp0uZ1Ap366o5syvqE-5RLWrIws,7771
|
|
77
|
+
shepherd_core-2024.8.2.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
78
|
+
shepherd_core-2024.8.2.dist-info/top_level.txt,sha256=wy-t7HRBrKARZxa-Y8_j8d49oVHnulh-95K9ikxVhew,14
|
|
79
|
+
shepherd_core-2024.8.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
80
|
+
shepherd_core-2024.8.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|