shepherd-data 2025.2.2__py3-none-any.whl → 2025.4.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_data/__init__.py +1 -1
- shepherd_data/cli.py +65 -23
- shepherd_data/ivonne.py +6 -6
- shepherd_data/mppt.py +5 -1
- shepherd_data/reader.py +18 -16
- {shepherd_data-2025.2.2.dist-info → shepherd_data-2025.4.2.dist-info}/METADATA +4 -5
- shepherd_data-2025.4.2.dist-info/RECORD +11 -0
- {shepherd_data-2025.2.2.dist-info → shepherd_data-2025.4.2.dist-info}/WHEEL +1 -1
- shepherd_data-2025.2.2.dist-info/RECORD +0 -11
- {shepherd_data-2025.2.2.dist-info → shepherd_data-2025.4.2.dist-info}/entry_points.txt +0 -0
- {shepherd_data-2025.2.2.dist-info → shepherd_data-2025.4.2.dist-info}/top_level.txt +0 -0
- {shepherd_data-2025.2.2.dist-info → shepherd_data-2025.4.2.dist-info}/zip-safe +0 -0
shepherd_data/__init__.py
CHANGED
shepherd_data/cli.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"""Command definitions for CLI."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
import os
|
|
5
4
|
import sys
|
|
6
5
|
from contextlib import suppress
|
|
7
6
|
from datetime import datetime
|
|
8
7
|
from pathlib import Path
|
|
9
|
-
from typing import List
|
|
10
8
|
from typing import Optional
|
|
11
9
|
|
|
12
10
|
import click
|
|
@@ -22,7 +20,7 @@ from .reader import Reader
|
|
|
22
20
|
logger = logging.getLogger("SHPData.cli")
|
|
23
21
|
|
|
24
22
|
|
|
25
|
-
def path_to_flist(data_path: Path) ->
|
|
23
|
+
def path_to_flist(data_path: Path, *, recurse: bool = False) -> list[Path]:
|
|
26
24
|
"""Every path gets transformed to a list of paths.
|
|
27
25
|
|
|
28
26
|
Transformations:
|
|
@@ -31,16 +29,14 @@ def path_to_flist(data_path: Path) -> List[Path]:
|
|
|
31
29
|
- or else: empty list
|
|
32
30
|
"""
|
|
33
31
|
data_path = Path(data_path).resolve()
|
|
34
|
-
h5files = []
|
|
32
|
+
h5files: list = []
|
|
35
33
|
if data_path.is_file() and data_path.suffix.lower() == ".h5":
|
|
36
34
|
h5files.append(data_path)
|
|
37
35
|
elif data_path.is_dir():
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
continue
|
|
43
|
-
h5files.append(fpath)
|
|
36
|
+
files = data_path.glob(
|
|
37
|
+
"**/*.h5" if recurse else "*.h5"
|
|
38
|
+
) # for py>=3.12: case_sensitive=False
|
|
39
|
+
h5files = [file for file in files if file.is_file()]
|
|
44
40
|
return h5files
|
|
45
41
|
|
|
46
42
|
|
|
@@ -70,9 +66,15 @@ def version() -> None:
|
|
|
70
66
|
|
|
71
67
|
@cli.command(short_help="Validates a file or directory containing shepherd-recordings")
|
|
72
68
|
@click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
|
|
73
|
-
|
|
69
|
+
@click.option(
|
|
70
|
+
"--recurse",
|
|
71
|
+
"-a",
|
|
72
|
+
is_flag=True,
|
|
73
|
+
help="Also consider files in sub-folders",
|
|
74
|
+
)
|
|
75
|
+
def validate(in_data: Path, *, recurse: bool = False) -> None:
|
|
74
76
|
"""Validate a file or directory containing shepherd-recordings."""
|
|
75
|
-
files = path_to_flist(in_data)
|
|
77
|
+
files = path_to_flist(in_data, recurse=recurse)
|
|
76
78
|
verbose_level = get_verbose_level() # TODO: should be stored and passed in ctx
|
|
77
79
|
valid_dir = True
|
|
78
80
|
for file in files:
|
|
@@ -123,7 +125,13 @@ def validate(in_data: Path) -> None:
|
|
|
123
125
|
"--raw",
|
|
124
126
|
"-r",
|
|
125
127
|
is_flag=True,
|
|
126
|
-
help="
|
|
128
|
+
help="Don't convert data to si-units",
|
|
129
|
+
)
|
|
130
|
+
@click.option(
|
|
131
|
+
"--recurse",
|
|
132
|
+
"-a",
|
|
133
|
+
is_flag=True,
|
|
134
|
+
help="Also consider files in sub-folders",
|
|
127
135
|
)
|
|
128
136
|
def extract(
|
|
129
137
|
in_data: Path,
|
|
@@ -133,9 +141,10 @@ def extract(
|
|
|
133
141
|
separator: str,
|
|
134
142
|
*,
|
|
135
143
|
raw: bool = False,
|
|
144
|
+
recurse: bool = False,
|
|
136
145
|
) -> None:
|
|
137
146
|
"""Extract recorded IVSamples and store them to csv."""
|
|
138
|
-
files = path_to_flist(in_data)
|
|
147
|
+
files = path_to_flist(in_data, recurse=recurse)
|
|
139
148
|
verbose_level = get_verbose_level()
|
|
140
149
|
if not isinstance(ds_factor, (float, int)) or ds_factor < 1:
|
|
141
150
|
ds_factor = 1000
|
|
@@ -162,10 +171,15 @@ def extract(
|
|
|
162
171
|
type=click.STRING,
|
|
163
172
|
help="Set an individual csv-separator",
|
|
164
173
|
)
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
@click.option(
|
|
175
|
+
"--recurse",
|
|
176
|
+
"-a",
|
|
177
|
+
is_flag=True,
|
|
178
|
+
help="Also consider files in sub-folders",
|
|
179
|
+
)
|
|
180
|
+
def extract_meta(in_data: Path, separator: str, *, recurse: bool = False) -> None:
|
|
167
181
|
"""Extract metadata and logs from file or directory containing shepherd-recordings."""
|
|
168
|
-
files = path_to_flist(in_data)
|
|
182
|
+
files = path_to_flist(in_data, recurse=recurse)
|
|
169
183
|
verbose_level = get_verbose_level()
|
|
170
184
|
for file in files:
|
|
171
185
|
logger.info("Extracting metadata & logs from '%s' ...", file.name)
|
|
@@ -195,9 +209,15 @@ def extract_meta(in_data: Path, separator: str) -> None:
|
|
|
195
209
|
short_help="Extracts uart from gpio-trace in file or directory containing shepherd-recordings"
|
|
196
210
|
)
|
|
197
211
|
@click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
|
|
198
|
-
|
|
212
|
+
@click.option(
|
|
213
|
+
"--recurse",
|
|
214
|
+
"-a",
|
|
215
|
+
is_flag=True,
|
|
216
|
+
help="Also consider files in sub-folders",
|
|
217
|
+
)
|
|
218
|
+
def extract_uart(in_data: Path, *, recurse: bool = False) -> None:
|
|
199
219
|
"""Extract UART from GPIO-trace in file or directory containing shepherd-recordings."""
|
|
200
|
-
files = path_to_flist(in_data)
|
|
220
|
+
files = path_to_flist(in_data, recurse=recurse)
|
|
201
221
|
verbose_level = get_verbose_level()
|
|
202
222
|
for file in files:
|
|
203
223
|
logger.info("Extracting uart from gpio-trace from from '%s' ...", file.name)
|
|
@@ -220,6 +240,7 @@ def extract_uart(in_data: Path) -> None:
|
|
|
220
240
|
log_file.write(timestamp.strftime("%Y-%m-%d %H:%M:%S.%f") + ":")
|
|
221
241
|
# TODO: allow to skip Timestamp and export raw text
|
|
222
242
|
log_file.write(f"\t{str.encode(line[1])}")
|
|
243
|
+
# TODO: does this produce "\tb'abc'"?
|
|
223
244
|
log_file.write("\n")
|
|
224
245
|
except TypeError:
|
|
225
246
|
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
@@ -233,10 +254,16 @@ def extract_uart(in_data: Path) -> None:
|
|
|
233
254
|
default=";",
|
|
234
255
|
type=click.STRING,
|
|
235
256
|
help="Set an individual csv-separator",
|
|
257
|
+
) # TODO: also configure decimal point
|
|
258
|
+
@click.option(
|
|
259
|
+
"--recurse",
|
|
260
|
+
"-a",
|
|
261
|
+
is_flag=True,
|
|
262
|
+
help="Also consider files in sub-folders",
|
|
236
263
|
)
|
|
237
|
-
def extract_gpio(in_data: Path, separator: str) -> None:
|
|
264
|
+
def extract_gpio(in_data: Path, separator: str, *, recurse: bool = False) -> None:
|
|
238
265
|
"""Extract UART from gpio-trace in file or directory containing shepherd-recordings."""
|
|
239
|
-
files = path_to_flist(in_data)
|
|
266
|
+
files = path_to_flist(in_data, recurse=recurse)
|
|
240
267
|
verbose_level = get_verbose_level()
|
|
241
268
|
for file in files:
|
|
242
269
|
logger.info("Extracting gpio-trace from from '%s' ...", file.name)
|
|
@@ -281,15 +308,23 @@ def extract_gpio(in_data: Path, separator: str) -> None:
|
|
|
281
308
|
type=click.FLOAT,
|
|
282
309
|
help="End-point in seconds, will be max if omitted",
|
|
283
310
|
)
|
|
311
|
+
@click.option(
|
|
312
|
+
"--recurse",
|
|
313
|
+
"-a",
|
|
314
|
+
is_flag=True,
|
|
315
|
+
help="Also consider files in sub-folders",
|
|
316
|
+
)
|
|
284
317
|
def downsample(
|
|
285
318
|
in_data: Path,
|
|
286
319
|
ds_factor: Optional[float],
|
|
287
320
|
sample_rate: Optional[int],
|
|
288
321
|
start: Optional[float],
|
|
289
322
|
end: Optional[float],
|
|
323
|
+
*,
|
|
324
|
+
recurse: bool = False,
|
|
290
325
|
) -> None:
|
|
291
326
|
"""Create an array of down-sampled files from file or dir containing shepherd-recordings."""
|
|
292
|
-
files = path_to_flist(in_data)
|
|
327
|
+
files = path_to_flist(in_data, recurse=recurse)
|
|
293
328
|
verbose_level = get_verbose_level()
|
|
294
329
|
for file in files:
|
|
295
330
|
try:
|
|
@@ -351,6 +386,12 @@ def downsample(
|
|
|
351
386
|
is_flag=True,
|
|
352
387
|
help="Plot only power instead of voltage, current & power",
|
|
353
388
|
)
|
|
389
|
+
@click.option(
|
|
390
|
+
"--recurse",
|
|
391
|
+
"-a",
|
|
392
|
+
is_flag=True,
|
|
393
|
+
help="Also consider files in sub-folders",
|
|
394
|
+
)
|
|
354
395
|
def plot(
|
|
355
396
|
in_data: Path,
|
|
356
397
|
start: Optional[float],
|
|
@@ -360,9 +401,10 @@ def plot(
|
|
|
360
401
|
*,
|
|
361
402
|
multiplot: bool,
|
|
362
403
|
only_power: bool,
|
|
404
|
+
recurse: bool = False,
|
|
363
405
|
) -> None:
|
|
364
406
|
"""Plot IV-trace from file or directory containing shepherd-recordings."""
|
|
365
|
-
files = path_to_flist(in_data)
|
|
407
|
+
files = path_to_flist(in_data, recurse=recurse)
|
|
366
408
|
verbose_level = get_verbose_level()
|
|
367
409
|
multiplot = multiplot and len(files) > 1
|
|
368
410
|
data = []
|
shepherd_data/ivonne.py
CHANGED
|
@@ -17,14 +17,14 @@ import pickle
|
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
from types import TracebackType
|
|
19
19
|
from typing import Optional
|
|
20
|
-
from typing import Type
|
|
21
20
|
|
|
22
21
|
import numpy as np
|
|
23
22
|
import pandas as pd
|
|
24
23
|
from tqdm import trange
|
|
25
24
|
from typing_extensions import Self
|
|
26
25
|
|
|
27
|
-
from . import Writer
|
|
26
|
+
from shepherd_core.writer import Writer as CoreWriter
|
|
27
|
+
|
|
28
28
|
from .mppt import MPPTracker
|
|
29
29
|
from .mppt import OptimalTracker
|
|
30
30
|
from .mppt import iv_model
|
|
@@ -88,7 +88,7 @@ class Reader:
|
|
|
88
88
|
|
|
89
89
|
def __exit__(
|
|
90
90
|
self,
|
|
91
|
-
typ: Optional[
|
|
91
|
+
typ: Optional[type[BaseException]] = None,
|
|
92
92
|
exc: Optional[BaseException] = None,
|
|
93
93
|
tb: Optional[TracebackType] = None,
|
|
94
94
|
extra_arg: int = 0,
|
|
@@ -132,7 +132,7 @@ class Reader:
|
|
|
132
132
|
|
|
133
133
|
v_proto = np.linspace(0, v_max, pts_per_curve)
|
|
134
134
|
|
|
135
|
-
with
|
|
135
|
+
with CoreWriter(shp_output, datatype="ivcurve", window_samples=pts_per_curve) as sfw:
|
|
136
136
|
sfw.store_hostname("IVonne")
|
|
137
137
|
curve_interval_us = round(sfw.sample_interval_ns * pts_per_curve / 1000)
|
|
138
138
|
up_factor = self.sample_interval_ns // sfw.sample_interval_ns
|
|
@@ -207,7 +207,7 @@ class Reader:
|
|
|
207
207
|
v_max,
|
|
208
208
|
)
|
|
209
209
|
|
|
210
|
-
with
|
|
210
|
+
with CoreWriter(shp_output, datatype="ivsample") as sfw:
|
|
211
211
|
sfw.store_hostname("IVonne")
|
|
212
212
|
interval_us = round(sfw.sample_interval_ns / 1000)
|
|
213
213
|
up_factor = self.sample_interval_ns // sfw.sample_interval_ns
|
|
@@ -260,7 +260,7 @@ class Reader:
|
|
|
260
260
|
self._logger.info("File already exists, will skip '%s'", shp_output.name)
|
|
261
261
|
return
|
|
262
262
|
|
|
263
|
-
with
|
|
263
|
+
with CoreWriter(shp_output, datatype="isc_voc") as sfw:
|
|
264
264
|
sfw.store_hostname("IVonne")
|
|
265
265
|
interval_us = round(sfw.sample_interval_ns / 1000)
|
|
266
266
|
up_factor = self.sample_interval_ns // sfw.sample_interval_ns
|
shepherd_data/mppt.py
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
Might be exchanged by shepherds py-model of pru-harvesters.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
from abc import ABC
|
|
7
|
+
from abc import abstractmethod
|
|
8
|
+
|
|
6
9
|
import numpy as np
|
|
7
10
|
import pandas as pd
|
|
8
11
|
|
|
@@ -36,7 +39,7 @@ def find_oc(v_arr: np.ndarray, i_arr: np.ndarray, ratio: float = 0.05) -> np.nda
|
|
|
36
39
|
return v_arr[np.argmax(i_arr < i_arr[0] * ratio)]
|
|
37
40
|
|
|
38
41
|
|
|
39
|
-
class MPPTracker:
|
|
42
|
+
class MPPTracker(ABC):
|
|
40
43
|
"""Prototype for a MPPT-class.
|
|
41
44
|
|
|
42
45
|
:param v_max: Maximum voltage supported by shepherd
|
|
@@ -48,6 +51,7 @@ class MPPTracker:
|
|
|
48
51
|
self.v_max: float = v_max
|
|
49
52
|
self.v_proto: np.ndarray = np.linspace(0, v_max, pts_per_curve)
|
|
50
53
|
|
|
54
|
+
@abstractmethod
|
|
51
55
|
def process(self, coeffs: pd.DataFrame) -> pd.DataFrame:
|
|
52
56
|
"""Apply harvesting model to input data.
|
|
53
57
|
|
shepherd_data/reader.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Reader-Baseclass for opening shepherds hdf5-files."""
|
|
2
2
|
|
|
3
3
|
import math
|
|
4
|
+
from collections.abc import Mapping
|
|
5
|
+
from collections.abc import Sequence
|
|
4
6
|
from datetime import datetime
|
|
5
7
|
from pathlib import Path
|
|
6
|
-
from typing import Dict
|
|
7
8
|
from typing import Optional
|
|
8
9
|
from typing import Union
|
|
9
10
|
|
|
@@ -33,9 +34,9 @@ class Reader(CoreReader):
|
|
|
33
34
|
|
|
34
35
|
def __init__(
|
|
35
36
|
self,
|
|
36
|
-
file_path:
|
|
37
|
+
file_path: Path,
|
|
37
38
|
*,
|
|
38
|
-
verbose:
|
|
39
|
+
verbose: bool = True,
|
|
39
40
|
) -> None:
|
|
40
41
|
super().__init__(file_path, verbose=verbose)
|
|
41
42
|
|
|
@@ -56,12 +57,16 @@ class Reader(CoreReader):
|
|
|
56
57
|
if csv_path.exists():
|
|
57
58
|
self._logger.info("File already exists, will skip '%s'", csv_path.name)
|
|
58
59
|
return 0
|
|
59
|
-
datasets
|
|
60
|
+
datasets: list[str] = [
|
|
61
|
+
str(key) for key in h5_group if isinstance(h5_group[key], h5py.Dataset)
|
|
62
|
+
]
|
|
60
63
|
datasets.remove("time")
|
|
61
64
|
datasets = ["time", *datasets]
|
|
62
65
|
separator = separator.strip().ljust(2)
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
header_elements: list[str] = [
|
|
67
|
+
str(h5_group[key].attrs["description"]).replace(", ", separator) for key in datasets
|
|
68
|
+
]
|
|
69
|
+
header: str = separator.join(header_elements)
|
|
65
70
|
with csv_path.open("w", encoding="utf-8-sig") as csv_file:
|
|
66
71
|
self._logger.info("CSV-Generator will save '%s' to '%s'", h5_group.name, csv_path.name)
|
|
67
72
|
csv_file.write(header + "\n")
|
|
@@ -222,7 +227,7 @@ class Reader(CoreReader):
|
|
|
222
227
|
for _iter in trange(
|
|
223
228
|
0,
|
|
224
229
|
iterations,
|
|
225
|
-
desc=f"downsampling {data_src.name}",
|
|
230
|
+
desc=f"downsampling {data_src.name if isinstance(data_src, h5py.Dataset) else ''}",
|
|
226
231
|
leave=False,
|
|
227
232
|
disable=iterations < 8,
|
|
228
233
|
):
|
|
@@ -242,7 +247,7 @@ class Reader(CoreReader):
|
|
|
242
247
|
self,
|
|
243
248
|
start_s: Optional[float],
|
|
244
249
|
end_s: Optional[float],
|
|
245
|
-
ds_factor:
|
|
250
|
+
ds_factor: float,
|
|
246
251
|
) -> Path:
|
|
247
252
|
"""Cut source to given limits, downsample by factor and store result in separate file.
|
|
248
253
|
|
|
@@ -290,10 +295,7 @@ class Reader(CoreReader):
|
|
|
290
295
|
else:
|
|
291
296
|
cut_str = ""
|
|
292
297
|
|
|
293
|
-
if ds_factor > 1
|
|
294
|
-
ds_str = f".downsample_x{round(ds_factor)}"
|
|
295
|
-
else:
|
|
296
|
-
ds_str = ""
|
|
298
|
+
ds_str = f".downsample_x{round(ds_factor)}" if ds_factor > 1 else ""
|
|
297
299
|
|
|
298
300
|
dst_file = self.file_path.resolve().with_suffix(cut_str + ds_str + ".h5")
|
|
299
301
|
if dst_file.exists():
|
|
@@ -403,7 +405,7 @@ class Reader(CoreReader):
|
|
|
403
405
|
for _ in trange(
|
|
404
406
|
0,
|
|
405
407
|
iterations,
|
|
406
|
-
desc=f"resampling {data_src.name}",
|
|
408
|
+
desc=f"resampling {data_src.name if isinstance(data_src, h5py.Dataset) else ''}",
|
|
407
409
|
leave=False,
|
|
408
410
|
disable=iterations < 8,
|
|
409
411
|
):
|
|
@@ -456,7 +458,7 @@ class Reader(CoreReader):
|
|
|
456
458
|
end_s: Optional[float] = None,
|
|
457
459
|
*,
|
|
458
460
|
relative_timestamp: bool = True,
|
|
459
|
-
) -> Optional[
|
|
461
|
+
) -> Optional[dict]:
|
|
460
462
|
"""Provide down-sampled iv-data that can be fed into plot_to_file().
|
|
461
463
|
|
|
462
464
|
:param start_s: time in seconds, relative to start of recording
|
|
@@ -506,7 +508,7 @@ class Reader(CoreReader):
|
|
|
506
508
|
|
|
507
509
|
@staticmethod
|
|
508
510
|
def assemble_plot(
|
|
509
|
-
data: Union[
|
|
511
|
+
data: Union[Mapping, Sequence], width: int = 20, height: int = 10, *, only_pwr: bool = False
|
|
510
512
|
) -> plt.Figure:
|
|
511
513
|
"""Create the actual figure.
|
|
512
514
|
|
|
@@ -520,7 +522,7 @@ class Reader(CoreReader):
|
|
|
520
522
|
:return: figure
|
|
521
523
|
"""
|
|
522
524
|
# TODO: allow choosing freely from I, V, P, GPIO
|
|
523
|
-
if isinstance(data,
|
|
525
|
+
if isinstance(data, Mapping):
|
|
524
526
|
data = [data]
|
|
525
527
|
if only_pwr:
|
|
526
528
|
fig, ax = plt.subplots(1, 1, figsize=(width, height), layout="tight")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: shepherd_data
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.4.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>
|
|
@@ -18,7 +18,6 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
18
18
|
Classifier: Intended Audience :: Developers
|
|
19
19
|
Classifier: Intended Audience :: Information Technology
|
|
20
20
|
Classifier: Intended Audience :: Science/Research
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.9
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.10
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -27,7 +26,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
27
26
|
Classifier: License :: OSI Approved :: MIT License
|
|
28
27
|
Classifier: Operating System :: OS Independent
|
|
29
28
|
Classifier: Natural Language :: English
|
|
30
|
-
Requires-Python: >=3.
|
|
29
|
+
Requires-Python: >=3.9
|
|
31
30
|
Description-Content-Type: text/markdown
|
|
32
31
|
Requires-Dist: click
|
|
33
32
|
Requires-Dist: h5py
|
|
@@ -36,7 +35,7 @@ Requires-Dist: numpy
|
|
|
36
35
|
Requires-Dist: pandas>=2.0.0
|
|
37
36
|
Requires-Dist: pyYAML
|
|
38
37
|
Requires-Dist: scipy
|
|
39
|
-
Requires-Dist: shepherd-core[inventory]>=2025.
|
|
38
|
+
Requires-Dist: shepherd-core[inventory]>=2025.04.2
|
|
40
39
|
Requires-Dist: tqdm
|
|
41
40
|
Provides-Extra: elf
|
|
42
41
|
Requires-Dist: shepherd-core[elf]; extra == "elf"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
shepherd_data/__init__.py,sha256=y1kOe2aqvWM7s5JHNJemMxTbZn4k_X7XPCOvdFWJIsI,353
|
|
2
|
+
shepherd_data/cli.py,sha256=ZrCFtWGXmfREux5a7XcdTEzmm7w4P0HMlURvVr_dkAw,14737
|
|
3
|
+
shepherd_data/ivonne.py,sha256=TG0ATldv2nSFXAaHtfTZixH43pjSlIcohfXneZ9hOCU,11922
|
|
4
|
+
shepherd_data/mppt.py,sha256=lBzcRttbqlsJLTHqofdx9vM6Yp8I_xNCEj9Ipsc-xY8,4002
|
|
5
|
+
shepherd_data/reader.py,sha256=i7mGpqmaMfHVZ5n_GcUrEL-Z-aWKjAW0SLH05buSGjo,24610
|
|
6
|
+
shepherd_data-2025.4.2.dist-info/METADATA,sha256=F-dwas6BCK7qXqBZhbFQGJLeS_xdp_9eVj7GCmIjiLg,3380
|
|
7
|
+
shepherd_data-2025.4.2.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
|
|
8
|
+
shepherd_data-2025.4.2.dist-info/entry_points.txt,sha256=6PBfY36A1xNOdzLiz-Qoukya_UzFZAwOapwmRNnPeZ8,56
|
|
9
|
+
shepherd_data-2025.4.2.dist-info/top_level.txt,sha256=7-SCTY-TG1mLY72OVKCaqte1hy-X8woxknIUAD3OIxs,14
|
|
10
|
+
shepherd_data-2025.4.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
11
|
+
shepherd_data-2025.4.2.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
shepherd_data/__init__.py,sha256=gP0M4X26bOl6FyEu8sTnpl_rG4UNMO3scijBzaeGSD0,353
|
|
2
|
-
shepherd_data/cli.py,sha256=6ndpKTZxXYOIogOTxD0Eqha6TtRSLn7_Imd_T6wzidA,13670
|
|
3
|
-
shepherd_data/ivonne.py,sha256=IaHy7RizdaaLAo-cQS-S5xQW_TzHW3dcJjb9hkTLjjY,11900
|
|
4
|
-
shepherd_data/mppt.py,sha256=588KSrLuJfNRKKnnL6ewePLi3zrwaO_PAZypikACrks,3925
|
|
5
|
-
shepherd_data/reader.py,sha256=zmxFkiiUC3o21qEjJbfr2Wpvpf5UjQQX9BSPkB2mug8,24457
|
|
6
|
-
shepherd_data-2025.2.2.dist-info/METADATA,sha256=V6CNIIukari9urobYQf0xAyej4ZdEpffSN44sJvH8EU,3430
|
|
7
|
-
shepherd_data-2025.2.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
8
|
-
shepherd_data-2025.2.2.dist-info/entry_points.txt,sha256=6PBfY36A1xNOdzLiz-Qoukya_UzFZAwOapwmRNnPeZ8,56
|
|
9
|
-
shepherd_data-2025.2.2.dist-info/top_level.txt,sha256=7-SCTY-TG1mLY72OVKCaqte1hy-X8woxknIUAD3OIxs,14
|
|
10
|
-
shepherd_data-2025.2.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
11
|
-
shepherd_data-2025.2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|