shepherd-data 2023.12.1__tar.gz → 2024.4.2__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_data-2024.4.2/PKG-INFO +88 -0
- shepherd_data-2024.4.2/README.md +38 -0
- shepherd_data-2024.4.2/pyproject.toml +101 -0
- shepherd_data-2024.4.2/setup.cfg +4 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data/__init__.py +8 -5
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data/cli.py +29 -29
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data/ivonne.py +11 -11
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data/mppt.py +22 -15
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data/reader.py +31 -23
- shepherd_data-2024.4.2/shepherd_data.egg-info/PKG-INFO +88 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data.egg-info/SOURCES.txt +5 -17
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data.egg-info/requires.txt +6 -4
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data.egg-info/top_level.txt +0 -1
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/tests/test_examples.py +3 -2
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/tests/test_ivonne.py +1 -1
- shepherd_data-2023.12.1/PKG-INFO +0 -274
- shepherd_data-2023.12.1/README.md +0 -224
- shepherd_data-2023.12.1/pyproject.toml +0 -7
- shepherd_data-2023.12.1/setup.cfg +0 -82
- shepherd_data-2023.12.1/shepherd_data/debug_resampler.py +0 -30
- shepherd_data-2023.12.1/shepherd_data.egg-info/PKG-INFO +0 -274
- shepherd_data-2023.12.1/tests/__init__.py +0 -0
- shepherd_data-2023.12.1/tests/conftest.py +0 -33
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data.egg-info/dependency_links.txt +0 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data.egg-info/entry_points.txt +0 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/shepherd_data.egg-info/zip-safe +0 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/tests/test_cli.py +0 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/tests/test_cli_downsample.py +0 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/tests/test_cli_extract.py +0 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/tests/test_cli_plot.py +0 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/tests/test_cli_validate.py +0 -0
- {shepherd_data-2023.12.1 → shepherd_data-2024.4.2}/tests/test_reader.py +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: shepherd_data
|
|
3
|
+
Version: 2024.4.2
|
|
4
|
+
Summary: Programming- and CLI-Interface for the h5-dataformat of the Shepherd-Testbed
|
|
5
|
+
Author-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
|
|
6
|
+
Maintainer-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
|
|
7
|
+
Project-URL: Documentation, https://github.com/orgua/shepherd-datalib/blob/main/README.md
|
|
8
|
+
Project-URL: Issues, https://pypi.org/project/shepherd-data/issues
|
|
9
|
+
Project-URL: Source, https://pypi.org/project/shepherd-data/
|
|
10
|
+
Keywords: testbed,beaglebone,pru,batteryless,energyharvesting,solar
|
|
11
|
+
Platform: unix
|
|
12
|
+
Platform: linux
|
|
13
|
+
Platform: osx
|
|
14
|
+
Platform: cygwin
|
|
15
|
+
Platform: win32
|
|
16
|
+
Platform: win64
|
|
17
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
18
|
+
Classifier: Intended Audience :: Developers
|
|
19
|
+
Classifier: Intended Audience :: Information Technology
|
|
20
|
+
Classifier: Intended Audience :: Science/Research
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
27
|
+
Classifier: Operating System :: OS Independent
|
|
28
|
+
Classifier: Natural Language :: English
|
|
29
|
+
Requires-Python: >=3.8
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
Requires-Dist: click
|
|
32
|
+
Requires-Dist: h5py
|
|
33
|
+
Requires-Dist: matplotlib
|
|
34
|
+
Requires-Dist: numpy
|
|
35
|
+
Requires-Dist: pandas>=2.0.0
|
|
36
|
+
Requires-Dist: pyYAML
|
|
37
|
+
Requires-Dist: scipy
|
|
38
|
+
Requires-Dist: shepherd-core[inventory]>=2024.4.2
|
|
39
|
+
Requires-Dist: tqdm
|
|
40
|
+
Provides-Extra: elf
|
|
41
|
+
Requires-Dist: shepherd-core[elf]; extra == "elf"
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: shepherd-core[dev]; extra == "dev"
|
|
44
|
+
Requires-Dist: pandas-stubs; extra == "dev"
|
|
45
|
+
Provides-Extra: test
|
|
46
|
+
Requires-Dist: shepherd-core[test]; extra == "test"
|
|
47
|
+
Requires-Dist: pytest; extra == "test"
|
|
48
|
+
Requires-Dist: pytest-click; extra == "test"
|
|
49
|
+
Requires-Dist: coverage; extra == "test"
|
|
50
|
+
|
|
51
|
+
# Shepherd-Data-Tool
|
|
52
|
+
|
|
53
|
+
[](https://pypi.org/project/shepherd_data)
|
|
54
|
+
[](https://pypi.python.org/pypi/shepherd-data)
|
|
55
|
+
[](https://github.com/orgua/shepherd-datalib/actions/workflows/py_unittest.yml)
|
|
56
|
+
[](https://github.com/astral-sh/ruff)
|
|
57
|
+
|
|
58
|
+
**Main Documentation**: <https://orgua.github.io/shepherd>
|
|
59
|
+
|
|
60
|
+
**Source Code**: <https://github.com/orgua/shepherd-datalib>
|
|
61
|
+
|
|
62
|
+
**Main Project**: <https://github.com/orgua/shepherd>
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
`shepherd-data` eases the handling of hdf5-recordings used by the [shepherd](https://github.com/orgua/shepherd)-testbed. Users can read, validate and create files and also extract, down-sample and plot information.
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
### PIP - Online
|
|
71
|
+
|
|
72
|
+
```shell
|
|
73
|
+
pip3 install shepherd-data -U
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
For bleeding-edge-features or dev-work it is possible to install directly from GitHub-Sources (here `dev`-branch):
|
|
77
|
+
|
|
78
|
+
```Shell
|
|
79
|
+
pip install git+https://github.com/orgua/shepherd-datalib.git@dev#subdirectory=shepherd_data -U
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## More
|
|
83
|
+
|
|
84
|
+
Please consult the [official documentation](https://orgua.github.io/shepherd) for more, it covers:
|
|
85
|
+
|
|
86
|
+
- general context
|
|
87
|
+
- command-line interface
|
|
88
|
+
- programming interface
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Shepherd-Data-Tool
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/shepherd_data)
|
|
4
|
+
[](https://pypi.python.org/pypi/shepherd-data)
|
|
5
|
+
[](https://github.com/orgua/shepherd-datalib/actions/workflows/py_unittest.yml)
|
|
6
|
+
[](https://github.com/astral-sh/ruff)
|
|
7
|
+
|
|
8
|
+
**Main Documentation**: <https://orgua.github.io/shepherd>
|
|
9
|
+
|
|
10
|
+
**Source Code**: <https://github.com/orgua/shepherd-datalib>
|
|
11
|
+
|
|
12
|
+
**Main Project**: <https://github.com/orgua/shepherd>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
`shepherd-data` eases the handling of hdf5-recordings used by the [shepherd](https://github.com/orgua/shepherd)-testbed. Users can read, validate and create files and also extract, down-sample and plot information.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
### PIP - Online
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
pip3 install shepherd-data -U
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
For bleeding-edge-features or dev-work it is possible to install directly from GitHub-Sources (here `dev`-branch):
|
|
27
|
+
|
|
28
|
+
```Shell
|
|
29
|
+
pip install git+https://github.com/orgua/shepherd-datalib.git@dev#subdirectory=shepherd_data -U
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## More
|
|
33
|
+
|
|
34
|
+
Please consult the [official documentation](https://orgua.github.io/shepherd) for more, it covers:
|
|
35
|
+
|
|
36
|
+
- general context
|
|
37
|
+
- command-line interface
|
|
38
|
+
- programming interface
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "shepherd_data"
|
|
3
|
+
description = "Programming- and CLI-Interface for the h5-dataformat of the Shepherd-Testbed"
|
|
4
|
+
keywords = ["testbed", "beaglebone", "pru", "batteryless", "energyharvesting", "solar"]
|
|
5
|
+
|
|
6
|
+
authors = [
|
|
7
|
+
{name = "Ingmar Splitt", email = "ingmar.splitt@tu-dresden.de"},
|
|
8
|
+
]
|
|
9
|
+
maintainers = [
|
|
10
|
+
{name = "Ingmar Splitt", email = "ingmar.splitt@tu-dresden.de"},
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
readme = {file = "README.md", content-type = "text/markdown"}
|
|
14
|
+
license = {file = "LICENSE"}
|
|
15
|
+
dynamic = ["version"]
|
|
16
|
+
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 5 - Production/Stable",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Intended Audience :: Information Technology",
|
|
21
|
+
"Intended Audience :: Science/Research",
|
|
22
|
+
"Programming Language :: Python :: 3.8",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"License :: OSI Approved :: MIT License",
|
|
28
|
+
"Operating System :: OS Independent",
|
|
29
|
+
"Natural Language :: English",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
requires-python = ">=3.8"
|
|
33
|
+
dependencies = [
|
|
34
|
+
"click",
|
|
35
|
+
"h5py",
|
|
36
|
+
"matplotlib", # full-version
|
|
37
|
+
"numpy",
|
|
38
|
+
"pandas>=2.0.0", # full-version, v2 is OK
|
|
39
|
+
"pyYAML",
|
|
40
|
+
"scipy", # full-version
|
|
41
|
+
"shepherd-core[inventory]>=2024.4.2",
|
|
42
|
+
"tqdm", # full-version
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
elf = [
|
|
47
|
+
"shepherd-core[elf]"
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
dev = [
|
|
51
|
+
"shepherd-core[dev]",
|
|
52
|
+
"pandas-stubs", # for pyright with pandas
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
test = [
|
|
56
|
+
"shepherd-core[test]",
|
|
57
|
+
"pytest",
|
|
58
|
+
"pytest-click",
|
|
59
|
+
"coverage",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
[project.urls]
|
|
63
|
+
Documentation = "https://github.com/orgua/shepherd-datalib/blob/main/README.md"
|
|
64
|
+
Issues = "https://pypi.org/project/shepherd-data/issues"
|
|
65
|
+
Source = "https://pypi.org/project/shepherd-data/"
|
|
66
|
+
|
|
67
|
+
[project.scripts]
|
|
68
|
+
shepherd-data = "shepherd_data.cli:cli"
|
|
69
|
+
|
|
70
|
+
[build-system]
|
|
71
|
+
requires = ["setuptools"]
|
|
72
|
+
build-backend = "setuptools.build_meta"
|
|
73
|
+
|
|
74
|
+
[tool.setuptools]
|
|
75
|
+
platforms = ["unix", "linux", "osx", "cygwin", "win32", "win64"]
|
|
76
|
+
zip-safe = true
|
|
77
|
+
#include-package-data = true
|
|
78
|
+
|
|
79
|
+
[tool.setuptools.package-dir]
|
|
80
|
+
shepherd_data = "shepherd_data"
|
|
81
|
+
|
|
82
|
+
[tool.setuptools.package-data]
|
|
83
|
+
shepherd_data = [
|
|
84
|
+
"README.md",
|
|
85
|
+
"src/examples/*.py",
|
|
86
|
+
"src/examples/*.iv",
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
[tool.setuptools.dynamic]
|
|
90
|
+
version = {attr = "shepherd_data.__version__"}
|
|
91
|
+
|
|
92
|
+
[tool.pytest.ini_options]
|
|
93
|
+
addopts = "-vvv --stepwise" # opts: verbose result for each tests
|
|
94
|
+
# TODO: add something like "--cov --cov-report html --cov-report term-missing --cov-fail-under 95"
|
|
95
|
+
|
|
96
|
+
[tool.coverage.run]
|
|
97
|
+
source = ["shepherd_data"]
|
|
98
|
+
|
|
99
|
+
[tool.mypy]
|
|
100
|
+
python_version = 3.8
|
|
101
|
+
ignore_missing_imports = true
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
"""
|
|
2
|
-
~~~~~
|
|
3
|
-
Provides classes for storing and retrieving sampled IV data to/from
|
|
4
|
-
HDF5 files.
|
|
1
|
+
"""Provides higher functionality compared to core, with additional lib-requirements.
|
|
5
2
|
|
|
3
|
+
Provides classes for storing and retrieving sampled IV data to/from
|
|
4
|
+
HDF5 files, with
|
|
5
|
+
- resampling
|
|
6
|
+
- plotting
|
|
7
|
+
- extracting metadata
|
|
6
8
|
"""
|
|
9
|
+
|
|
7
10
|
from shepherd_core import Writer
|
|
8
11
|
|
|
9
12
|
from .reader import Reader
|
|
10
13
|
|
|
11
|
-
__version__ = "
|
|
14
|
+
__version__ = "2024.4.2"
|
|
12
15
|
|
|
13
16
|
__all__ = [
|
|
14
17
|
"Reader",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"""Command definitions for CLI
|
|
2
|
-
|
|
1
|
+
"""Command definitions for CLI."""
|
|
2
|
+
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
5
|
import sys
|
|
@@ -16,15 +16,17 @@ from shepherd_core import increase_verbose_level
|
|
|
16
16
|
from shepherd_core import local_tz
|
|
17
17
|
from shepherd_core.commons import samplerate_sps_default
|
|
18
18
|
|
|
19
|
-
from . import Reader
|
|
20
19
|
from . import Writer
|
|
21
20
|
from . import __version__
|
|
21
|
+
from .reader import Reader
|
|
22
22
|
|
|
23
23
|
logger = logging.getLogger("SHPData.cli")
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def path_to_flist(data_path: Path) -> List[Path]:
|
|
27
|
-
"""Every path gets transformed to a list of paths
|
|
27
|
+
"""Every path gets transformed to a list of paths.
|
|
28
|
+
|
|
29
|
+
Transformations:
|
|
28
30
|
- if directory: list of files inside
|
|
29
31
|
- if existing file: list with 1 element
|
|
30
32
|
- or else: empty list
|
|
@@ -57,7 +59,7 @@ def path_to_flist(data_path: Path) -> List[Path]:
|
|
|
57
59
|
)
|
|
58
60
|
@click.pass_context # TODO: is the ctx-type correct?
|
|
59
61
|
def cli(ctx: click.Context, verbose: bool, version: bool) -> None: # noqa: FBT001
|
|
60
|
-
"""Shepherd: Synchronized Energy Harvesting Emulator and Recorder"""
|
|
62
|
+
"""Shepherd: Synchronized Energy Harvesting Emulator and Recorder."""
|
|
61
63
|
if verbose:
|
|
62
64
|
increase_verbose_level(3)
|
|
63
65
|
if version:
|
|
@@ -71,7 +73,7 @@ def cli(ctx: click.Context, verbose: bool, version: bool) -> None: # noqa: FBT0
|
|
|
71
73
|
@cli.command(short_help="Validates a file or directory containing shepherd-recordings")
|
|
72
74
|
@click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
|
|
73
75
|
def validate(in_data: Path) -> None:
|
|
74
|
-
"""
|
|
76
|
+
"""Validate a file or directory containing shepherd-recordings."""
|
|
75
77
|
files = path_to_flist(in_data)
|
|
76
78
|
verbose_level = get_verbose_level() # TODO: should be stored and passed in ctx
|
|
77
79
|
valid_dir = True
|
|
@@ -85,8 +87,8 @@ def validate(in_data: Path) -> None:
|
|
|
85
87
|
valid_dir &= valid_file
|
|
86
88
|
if not valid_file:
|
|
87
89
|
logger.error(" -> File '%s' was NOT valid", file.name)
|
|
88
|
-
except TypeError
|
|
89
|
-
logger.
|
|
90
|
+
except TypeError:
|
|
91
|
+
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
90
92
|
sys.exit(int(not valid_dir))
|
|
91
93
|
|
|
92
94
|
|
|
@@ -107,7 +109,7 @@ def validate(in_data: Path) -> None:
|
|
|
107
109
|
help="Set an individual csv-separator",
|
|
108
110
|
)
|
|
109
111
|
def extract(in_data: Path, ds_factor: float, separator: str) -> None:
|
|
110
|
-
"""
|
|
112
|
+
"""Extract recorded IVSamples and store them to csv."""
|
|
111
113
|
files = path_to_flist(in_data)
|
|
112
114
|
verbose_level = get_verbose_level()
|
|
113
115
|
if not isinstance(ds_factor, (float, int)) or ds_factor < 1:
|
|
@@ -143,8 +145,8 @@ def extract(in_data: Path, ds_factor: float, separator: str) -> None:
|
|
|
143
145
|
|
|
144
146
|
with Reader(ds_file, verbose=verbose_level > 2) as shpd:
|
|
145
147
|
shpd.save_csv(shpd["data"], separator)
|
|
146
|
-
except TypeError
|
|
147
|
-
logger.
|
|
148
|
+
except TypeError:
|
|
149
|
+
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
148
150
|
|
|
149
151
|
|
|
150
152
|
@cli.command(
|
|
@@ -159,14 +161,14 @@ def extract(in_data: Path, ds_factor: float, separator: str) -> None:
|
|
|
159
161
|
help="Set an individual csv-separator",
|
|
160
162
|
)
|
|
161
163
|
def extract_meta(in_data: Path, separator: str) -> None:
|
|
162
|
-
"""
|
|
164
|
+
"""Extract metadata and logs from file or directory containing shepherd-recordings."""
|
|
163
165
|
files = path_to_flist(in_data)
|
|
164
166
|
verbose_level = get_verbose_level()
|
|
165
167
|
for file in files:
|
|
166
168
|
logger.info("Extracting metadata & logs from '%s' ...", file.name)
|
|
167
169
|
# TODO: add default exports (user-centric) and allow specifying --all or specific ones
|
|
168
170
|
# TODO: could also be combined with other extractors (just have one)
|
|
169
|
-
# TODO remove deprecated
|
|
171
|
+
# TODO: remove deprecated timesync; "shepherd-log", "dmesg", "exceptions"
|
|
170
172
|
try:
|
|
171
173
|
with Reader(file, verbose=verbose_level > 2) as shpr:
|
|
172
174
|
shpr.save_metadata()
|
|
@@ -181,8 +183,8 @@ def extract_meta(in_data: Path, separator: str) -> None:
|
|
|
181
183
|
# TODO: allow omitting timestamp,
|
|
182
184
|
# also test if segmented uart is correctly written
|
|
183
185
|
shpr.warn_logs(element, show=True)
|
|
184
|
-
except TypeError
|
|
185
|
-
logger.
|
|
186
|
+
except TypeError:
|
|
187
|
+
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
186
188
|
|
|
187
189
|
|
|
188
190
|
@cli.command(
|
|
@@ -190,7 +192,7 @@ def extract_meta(in_data: Path, separator: str) -> None:
|
|
|
190
192
|
)
|
|
191
193
|
@click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
|
|
192
194
|
def extract_uart(in_data: Path) -> None:
|
|
193
|
-
"""
|
|
195
|
+
"""Extract UART from GPIO-trace in file or directory containing shepherd-recordings."""
|
|
194
196
|
files = path_to_flist(in_data)
|
|
195
197
|
verbose_level = get_verbose_level()
|
|
196
198
|
for file in files:
|
|
@@ -213,8 +215,8 @@ def extract_uart(in_data: Path) -> None:
|
|
|
213
215
|
# TODO: allow to skip Timestamp and export raw text
|
|
214
216
|
log_file.write(f"\t{str.encode(line[1])}")
|
|
215
217
|
log_file.write("\n")
|
|
216
|
-
except TypeError
|
|
217
|
-
logger.
|
|
218
|
+
except TypeError:
|
|
219
|
+
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
218
220
|
|
|
219
221
|
|
|
220
222
|
@cli.command(short_help="Extracts gpio-trace from file or directory containing shepherd-recordings")
|
|
@@ -227,7 +229,7 @@ def extract_uart(in_data: Path) -> None:
|
|
|
227
229
|
help="Set an individual csv-separator",
|
|
228
230
|
)
|
|
229
231
|
def extract_gpio(in_data: Path, separator: str) -> None:
|
|
230
|
-
"""
|
|
232
|
+
"""Extract UART from gpio-trace in file or directory containing shepherd-recordings."""
|
|
231
233
|
files = path_to_flist(in_data)
|
|
232
234
|
verbose_level = get_verbose_level()
|
|
233
235
|
for file in files:
|
|
@@ -237,8 +239,8 @@ def extract_gpio(in_data: Path, separator: str) -> None:
|
|
|
237
239
|
wfs = shpr.gpio_to_waveforms()
|
|
238
240
|
for name, wf in wfs.items():
|
|
239
241
|
shpr.waveform_to_csv(name, wf, separator)
|
|
240
|
-
except TypeError
|
|
241
|
-
logger.
|
|
242
|
+
except TypeError:
|
|
243
|
+
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
242
244
|
|
|
243
245
|
|
|
244
246
|
@cli.command(
|
|
@@ -261,9 +263,7 @@ def extract_gpio(in_data: Path, separator: str) -> None:
|
|
|
261
263
|
help="Alternative Input to determine a downsample-factor (Choose One)",
|
|
262
264
|
)
|
|
263
265
|
def downsample(in_data: Path, ds_factor: Optional[float], sample_rate: Optional[int]) -> None:
|
|
264
|
-
"""
|
|
265
|
-
or directory containing shepherd-recordings
|
|
266
|
-
"""
|
|
266
|
+
"""Create an array of down-sampled files from file or dir containing shepherd-recordings."""
|
|
267
267
|
if ds_factor is None and sample_rate is not None and sample_rate >= 1:
|
|
268
268
|
ds_factor = int(samplerate_sps_default / sample_rate)
|
|
269
269
|
# TODO: shouldn't current sps be based on file rather than default?
|
|
@@ -303,8 +303,8 @@ def downsample(in_data: Path, ds_factor: Optional[float], sample_rate: Optional[
|
|
|
303
303
|
shpr.downsample(shpr.ds_time, shpw.ds_time, ds_factor=_factor, is_time=True)
|
|
304
304
|
shpr.downsample(shpr.ds_voltage, shpw.ds_voltage, ds_factor=_factor)
|
|
305
305
|
shpr.downsample(shpr.ds_current, shpw.ds_current, ds_factor=_factor)
|
|
306
|
-
except TypeError
|
|
307
|
-
logger.
|
|
306
|
+
except TypeError:
|
|
307
|
+
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
308
308
|
|
|
309
309
|
|
|
310
310
|
@cli.command(short_help="Plots IV-trace from file or directory containing shepherd-recordings")
|
|
@@ -351,7 +351,7 @@ def plot(
|
|
|
351
351
|
height: int,
|
|
352
352
|
multiplot: bool, # noqa: FBT001
|
|
353
353
|
) -> None:
|
|
354
|
-
"""
|
|
354
|
+
"""Plot IV-trace from file or directory containing shepherd-recordings."""
|
|
355
355
|
files = path_to_flist(in_data)
|
|
356
356
|
verbose_level = get_verbose_level()
|
|
357
357
|
multiplot = multiplot and len(files) > 1
|
|
@@ -364,8 +364,8 @@ def plot(
|
|
|
364
364
|
data.append(shpr.generate_plot_data(start, end, relative_timestamp=True))
|
|
365
365
|
else:
|
|
366
366
|
shpr.plot_to_file(start, end, width, height)
|
|
367
|
-
except TypeError
|
|
368
|
-
logger.
|
|
367
|
+
except TypeError:
|
|
368
|
+
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
369
369
|
if multiplot:
|
|
370
370
|
logger.info("Got %d datasets to plot", len(data))
|
|
371
371
|
mpl_path = Reader.multiplot_to_file(data, in_data, width, height)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
"""
|
|
2
|
-
to generate valid shepherd-data for emulation
|
|
1
|
+
"""file-reader with various converters to generate valid shepherd-data for emulation."""
|
|
3
2
|
|
|
4
|
-
"""
|
|
5
3
|
import errno
|
|
6
4
|
import logging
|
|
7
5
|
import math
|
|
@@ -34,7 +32,7 @@ def get_isc(coeffs: pd.DataFrame): # noqa: ANN201
|
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
class Reader:
|
|
37
|
-
"""
|
|
35
|
+
"""Container for converters that bridge the gap to shepherds data-files."""
|
|
38
36
|
|
|
39
37
|
_logger: logging.Logger = logging.getLogger("SHPData.IVonne.Reader")
|
|
40
38
|
|
|
@@ -102,8 +100,9 @@ class Reader:
|
|
|
102
100
|
pts_per_curve: int = 1000,
|
|
103
101
|
duration_s: Optional[float] = None,
|
|
104
102
|
) -> None:
|
|
105
|
-
"""
|
|
106
|
-
|
|
103
|
+
"""Transform recorded parameters to shepherd hdf database with IV curves.
|
|
104
|
+
|
|
105
|
+
Shepherd works with IV 'surfaces', which is a stream of IV curves.
|
|
107
106
|
|
|
108
107
|
:param shp_output: Path where the resulting hdf file shall be stored
|
|
109
108
|
:param v_max: Maximum voltage supported by shepherd
|
|
@@ -134,7 +133,7 @@ class Reader:
|
|
|
134
133
|
for idx in job_iter:
|
|
135
134
|
idx_top = min(idx + max_elements, df_elements_n)
|
|
136
135
|
df_slice = self._df.iloc[idx : idx_top + 1].copy()
|
|
137
|
-
df_slice["timestamp"] = pd.
|
|
136
|
+
df_slice["timestamp"] = pd.to_timedelta(df_slice["time"], unit="s")
|
|
138
137
|
df_slice = df_slice.set_index("timestamp")
|
|
139
138
|
# warning: .interpolate does crash in debug-mode with typeError
|
|
140
139
|
df_slice = (
|
|
@@ -163,7 +162,7 @@ class Reader:
|
|
|
163
162
|
duration_s: Optional[float] = None,
|
|
164
163
|
tracker: Optional[MPPTracker] = None,
|
|
165
164
|
) -> None:
|
|
166
|
-
"""
|
|
165
|
+
"""Transform shepherd IV curves to shepherd IV samples / traces.
|
|
167
166
|
|
|
168
167
|
For the 'buck' and 'buck-boost' modes, shepherd takes voltage and current traces.
|
|
169
168
|
These can be recorded with shepherd or generated from existing IV curves by, for
|
|
@@ -180,6 +179,7 @@ class Reader:
|
|
|
180
179
|
:param v_max: Maximum voltage supported by shepherd
|
|
181
180
|
:param duration_s: time to stop in seconds, counted from beginning
|
|
182
181
|
:param tracker: VOC or OPT
|
|
182
|
+
|
|
183
183
|
"""
|
|
184
184
|
if self._df is None:
|
|
185
185
|
raise RuntimeError("IVonne Context was not entered - file not open!")
|
|
@@ -213,7 +213,7 @@ class Reader:
|
|
|
213
213
|
df_slice.loc[:, "voc"] = get_voc(df_slice)
|
|
214
214
|
df_slice.loc[df_slice["voc"] >= v_max, "voc"] = v_max
|
|
215
215
|
df_slice = tracker.process(df_slice)
|
|
216
|
-
df_slice["timestamp"] = pd.
|
|
216
|
+
df_slice["timestamp"] = pd.to_timedelta(df_slice["time"], unit="s")
|
|
217
217
|
df_slice = df_slice[["time", "v", "i", "timestamp"]].set_index("timestamp")
|
|
218
218
|
# warning: .interpolate does crash in debug-mode with typeError
|
|
219
219
|
df_slice = (
|
|
@@ -231,7 +231,7 @@ class Reader:
|
|
|
231
231
|
v_max: float = 5.0,
|
|
232
232
|
duration_s: Optional[float] = None,
|
|
233
233
|
) -> None:
|
|
234
|
-
"""
|
|
234
|
+
"""Transform ivonne-parameters to up-sampled versions for shepherd.
|
|
235
235
|
|
|
236
236
|
:param shp_output: Path where the resulting hdf file shall be stored
|
|
237
237
|
:param v_max: Maximum voltage supported by shepherd
|
|
@@ -264,7 +264,7 @@ class Reader:
|
|
|
264
264
|
df_slice.loc[:, "voc"] = get_voc(df_slice)
|
|
265
265
|
df_slice.loc[df_slice["voc"] >= v_max, "voc"] = v_max
|
|
266
266
|
df_slice.loc[:, "isc"] = get_isc(df_slice)
|
|
267
|
-
df_slice["timestamp"] = pd.
|
|
267
|
+
df_slice["timestamp"] = pd.to_timedelta(df_slice["time"], unit="s")
|
|
268
268
|
df_slice = df_slice[["time", "voc", "isc", "timestamp"]].set_index("timestamp")
|
|
269
269
|
# warning: .interpolate does crash in debug-mode with typeError
|
|
270
270
|
df_slice = (
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"""Harvesters, simple and fast approach.
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
Might be exchanged by shepherds py-model of pru-harvesters.
|
|
3
4
|
"""
|
|
5
|
+
|
|
4
6
|
import numpy as np
|
|
5
7
|
import pandas as pd
|
|
6
8
|
|
|
@@ -8,16 +10,11 @@ from shepherd_core import Calc_t
|
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
def iv_model(voltages: Calc_t, coeffs: pd.Series) -> Calc_t:
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
----
|
|
15
|
-
:param voltages: Load voltage of the solar panel
|
|
16
|
-
:param coeffs: three generic coefficients
|
|
13
|
+
"""Calculate simple diode based model (equivalent circuit diagram) of a solar panel IV curve.
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
:param voltages: Load voltage of the solar panel
|
|
16
|
+
:param coeffs: three generic coefficients
|
|
17
|
+
:return: Solar current at given load voltage
|
|
21
18
|
"""
|
|
22
19
|
currents = float(coeffs["a"]) - float(coeffs["b"]) * (
|
|
23
20
|
np.exp(float(coeffs["c"]) * voltages) - 1.0
|
|
@@ -40,7 +37,7 @@ def find_oc(v_arr: np.ndarray, i_arr: np.ndarray, ratio: float = 0.05) -> np.nda
|
|
|
40
37
|
|
|
41
38
|
|
|
42
39
|
class MPPTracker:
|
|
43
|
-
"""Prototype
|
|
40
|
+
"""Prototype for a MPPT-class.
|
|
44
41
|
|
|
45
42
|
:param v_max: Maximum voltage supported by shepherd
|
|
46
43
|
:param pts_per_curve: resolution of internal ivcurve
|
|
@@ -52,15 +49,15 @@ class MPPTracker:
|
|
|
52
49
|
self.v_proto: np.ndarray = np.linspace(0, v_max, pts_per_curve)
|
|
53
50
|
|
|
54
51
|
def process(self, coeffs: pd.DataFrame) -> pd.DataFrame:
|
|
55
|
-
"""Apply harvesting model to input data
|
|
52
|
+
"""Apply harvesting model to input data.
|
|
56
53
|
|
|
57
54
|
:param coeffs: ivonne coefficients
|
|
58
|
-
:return:
|
|
55
|
+
:return: ivsample-data
|
|
59
56
|
"""
|
|
60
57
|
|
|
61
58
|
|
|
62
59
|
class OpenCircuitTracker(MPPTracker):
|
|
63
|
-
"""Open-circuit based MPPT
|
|
60
|
+
"""Open-circuit (-voltage) based MPPT.
|
|
64
61
|
|
|
65
62
|
:param v_max: Maximum voltage supported by shepherd
|
|
66
63
|
:param pts_per_curve: resolution of internal ivcurve
|
|
@@ -72,6 +69,11 @@ class OpenCircuitTracker(MPPTracker):
|
|
|
72
69
|
self.ratio = ratio
|
|
73
70
|
|
|
74
71
|
def process(self, coeffs: pd.DataFrame) -> pd.DataFrame:
|
|
72
|
+
"""Apply harvesting model to input data.
|
|
73
|
+
|
|
74
|
+
:param coeffs: ivonne coefficients
|
|
75
|
+
:return: ivsample-data
|
|
76
|
+
"""
|
|
75
77
|
coeffs["icurve"] = coeffs.apply(lambda x: iv_model(self.v_proto, x), axis=1)
|
|
76
78
|
if "voc" not in coeffs.columns:
|
|
77
79
|
coeffs["voc"] = coeffs.apply(lambda x: find_oc(self.v_proto, x["ivcurve"]), axis=1)
|
|
@@ -85,7 +87,7 @@ class OpenCircuitTracker(MPPTracker):
|
|
|
85
87
|
|
|
86
88
|
|
|
87
89
|
class OptimalTracker(MPPTracker):
|
|
88
|
-
"""Optimal MPPT
|
|
90
|
+
"""Optimal MPPT by looking at the whole curve.
|
|
89
91
|
|
|
90
92
|
Calculates optimal harvesting voltage for every time and corresponding IV curve.
|
|
91
93
|
|
|
@@ -97,6 +99,11 @@ class OptimalTracker(MPPTracker):
|
|
|
97
99
|
super().__init__(v_max, pts_per_curve)
|
|
98
100
|
|
|
99
101
|
def process(self, coeffs: pd.DataFrame) -> pd.DataFrame:
|
|
102
|
+
"""Apply harvesting model to input data.
|
|
103
|
+
|
|
104
|
+
:param coeffs: ivonne coefficients
|
|
105
|
+
:return: ivsample-data
|
|
106
|
+
"""
|
|
100
107
|
coeffs["icurve"] = coeffs.apply(lambda x: iv_model(self.v_proto, x), axis=1)
|
|
101
108
|
coeffs["pcurve"] = coeffs.apply(lambda x: self.v_proto * x["icurve"], axis=1)
|
|
102
109
|
coeffs["max_pos"] = coeffs.apply(lambda x: np.argmax(x["pcurve"]), axis=1)
|