Skip to content

Commit 516ab1a

Browse files
authored
Merge pull request #16 from harp-tech/gl-dev
Add support to infer register data file path
2 parents a5c430b + 1ae16de commit 516ab1a

3 files changed

Lines changed: 45 additions & 11 deletions

File tree

harp/reader.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import os
12
import re
23
from math import log2
34
from os import PathLike
5+
from pathlib import Path
46
from functools import partial
57
from numpy import dtype
68
from pandas import DataFrame, Series
7-
from typing import Any, BinaryIO, Iterable, Callable, Optional, Union
9+
from typing import Any, BinaryIO, Iterable, Optional, Protocol, Union
810
from pandas._typing import Axes
911
from harp.model import BitMask, GroupMask, Model, PayloadMember, Register
1012
from harp.io import read
@@ -13,14 +15,21 @@
1315
_camel_to_snake_regex = re.compile(r"(?<!^)(?=[A-Z])")
1416

1517

18+
class _ReadRegister(Protocol):
19+
def __call__(
20+
self, file: Optional[Union[str, bytes, PathLike[Any], BinaryIO]] = None
21+
) -> DataFrame:
22+
...
23+
24+
1625
class RegisterReader:
1726
register: Register
18-
read: Callable[[Union[str, bytes, PathLike[Any], BinaryIO]], DataFrame]
27+
read: _ReadRegister
1928

2029
def __init__(
2130
self,
2231
register: Register,
23-
read: Callable[[Union[str, bytes, PathLike[Any], BinaryIO]], DataFrame],
32+
read: _ReadRegister,
2433
) -> None:
2534
self.register = register
2635
self.read = read
@@ -111,7 +120,7 @@ def parser(df: DataFrame):
111120
if member.mask is not None:
112121
series = series & member.mask
113122
if shift > 0:
114-
series = Series(series.values >> shift, series.index) # type: ignore
123+
series = Series(series.values >> shift, series.index) # type: ignore
115124
if is_boolean:
116125
series = series != 0
117126
elif lookup is not None:
@@ -121,10 +130,14 @@ def parser(df: DataFrame):
121130
return parser
122131

123132

124-
def _create_register_reader(register: Register):
133+
def _create_register_reader(register: Register, base_path: Path):
125134
def reader(
126-
file: Union[str, bytes, PathLike[Any], BinaryIO], columns: Optional[Axes] = None
135+
file: Optional[Union[str, bytes, PathLike[Any], BinaryIO]] = None,
136+
columns: Optional[Axes] = None,
127137
):
138+
if file is None:
139+
file = f"{base_path}_{register.address}.bin"
140+
128141
data = read(
129142
file,
130143
address=register.address,
@@ -137,9 +150,9 @@ def reader(
137150
return reader
138151

139152

140-
def _create_register_parser(device: Model, name: str):
153+
def _create_register_parser(device: Model, name: str, base_path: Path):
141154
register = device.registers[name]
142-
reader = _create_register_reader(register)
155+
reader = _create_register_reader(register, base_path)
143156

144157
if register.maskType is not None:
145158
key = register.maskType.root
@@ -172,9 +185,22 @@ def parser(df: DataFrame):
172185
return RegisterReader(register, reader)
173186

174187

175-
def create_reader(file: Union[str, PathLike], include_common_registers: bool = True):
176-
device = read_schema(file, include_common_registers)
188+
def create_reader(
189+
device: Union[str, PathLike, Model], include_common_registers: bool = True
190+
):
191+
if isinstance(device, Model):
192+
base_path = Path(device.device)
193+
else:
194+
path = Path(device).absolute().resolve()
195+
is_dir = os.path.isdir(path)
196+
if is_dir:
197+
device = path / "device.yml"
198+
199+
device = read_schema(device, include_common_registers)
200+
base_path = path / device.device if is_dir else path.parent / device.device
201+
177202
reg_readers = {
178-
name: _create_register_parser(device, name) for name in device.registers.keys()
203+
name: _create_register_parser(device, name, base_path)
204+
for name in device.registers.keys()
179205
}
180206
return DeviceReader(device, reg_readers)

tests/data/device_0.bin

0 Bytes
Binary file not shown.

tests/test_reader.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
from tests.params import DeviceSchemaParam
44

55
testdata = [
6+
DeviceSchemaParam(
7+
path="data",
8+
expected_whoAmI=0,
9+
expected_registers=["DigitalInputMode"],
10+
),
611
DeviceSchemaParam(
712
path="data/device.yml",
813
expected_whoAmI=0,
@@ -15,3 +20,6 @@
1520
def test_create_reader(schemaFile: DeviceSchemaParam):
1621
reader = create_reader(schemaFile.path)
1722
schemaFile.assert_schema(reader.device)
23+
24+
whoAmI = reader.WhoAmI.read()
25+
assert reader.device.whoAmI == whoAmI.iloc[0, 0]

0 commit comments

Comments
 (0)