Skip to content

Commit 6daba19

Browse files
committed
Add base implementation of register reader
1 parent 84db6f5 commit 6daba19

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

harp/reader.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import re
2+
from functools import partial, reduce
3+
from pandas import DataFrame
4+
from typing import Iterable, Callable
5+
from harp.model import Model, Register
6+
from harp.io import read
7+
8+
_camel_to_snake_regex = re.compile(r"(?<!^)(?=[A-Z])")
9+
10+
11+
class Reader:
12+
register: Register
13+
read: Callable[[str], DataFrame]
14+
15+
def __init__(self, register: Register, read: Callable[[str], DataFrame]) -> None:
16+
self.register = register
17+
self.read = read
18+
19+
20+
def compose(f, g):
21+
return lambda *a, **kw: f(g(*a, **kw))
22+
23+
24+
def id_camel_to_snake(id: str):
25+
return _camel_to_snake_regex.sub("_", id).lower()
26+
27+
28+
def keys_camel_to_snake(keys: Iterable[str]):
29+
return [id_camel_to_snake(k) for k in keys]
30+
31+
32+
def create_bitreader(mask):
33+
return lambda xs: ((xs & mask) != 0)
34+
35+
36+
def create_reader(device: Model, name: str):
37+
register = device.registers[name]
38+
reader = read
39+
40+
if register.maskType is not None:
41+
key = register.maskType.root
42+
bitMask = device.bitMasks.get(key)
43+
if bitMask is not None:
44+
lookup = [
45+
(id_camel_to_snake(k), create_bitreader(v.root))
46+
for k, v in bitMask.bits.items()
47+
]
48+
49+
def unpack(df):
50+
return DataFrame({n: f(df[0]) for n, f in lookup}, index=df.index)
51+
52+
reader = compose(unpack, reader)
53+
return Reader(register, reader)
54+
55+
groupMask = device.groupMasks.get(key)
56+
if groupMask is not None:
57+
name = id_camel_to_snake(name)
58+
lookup = {value.root: name for name, value in groupMask.values.items()}
59+
reader = partial(reader, columns=[name])
60+
reader = compose(lambda df: df.map(lambda x: lookup[x]), reader)
61+
return Reader(register, reader)
62+
63+
if register.payloadSpec is not None:
64+
columns = register.payloadSpec.keys()
65+
columns = keys_camel_to_snake(columns)
66+
reader = partial(reader, columns=columns)
67+
return Reader(register, reader)
68+
69+
columns = [id_camel_to_snake(name)]
70+
reader = partial(reader, columns=columns)
71+
return Reader(register, reader)

0 commit comments

Comments
 (0)