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.
@@ -15,7 +15,7 @@
15
15
  interval_startup_delay_drain_ms: 0
16
16
 
17
17
  harvester:
18
- name: mppt_opt # harvester only active if input is "ivcurves"
18
+ name: mppt_opt # harvester only active if input is "ivcurve"
19
19
 
20
20
  V_input_max_mV: 10000
21
21
  I_input_max_mA: 4200
shepherd_core/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Separated string avoids circular imports."""
2
2
 
3
- version: str = "2024.8.1"
3
+ version: str = "2024.8.2"
@@ -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.1
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=xmbickJLTzW9cd7jhYX7fdLN72fW-vKC8QWUEFq3lR4,75
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=qmtZp4Tcf5K8l65AjqOZhH-kDAaXs7YUIZNjJwaQhm8,10526
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=dS33KYLq5GQ9_D8HfdP8iWSocWTghCi2ZZG2AJWNfaM,391
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-2024.8.1.dist-info/METADATA,sha256=-DJfS_CoIctcSz8u4V-85AUpTYrcLVDZ0Pc8UQScNJI,7771
74
- shepherd_core-2024.8.1.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
75
- shepherd_core-2024.8.1.dist-info/top_level.txt,sha256=wy-t7HRBrKARZxa-Y8_j8d49oVHnulh-95K9ikxVhew,14
76
- shepherd_core-2024.8.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
77
- shepherd_core-2024.8.1.dist-info/RECORD,,
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,,