Skip to content

Commit 87b4934

Browse files
authored
Merge pull request #5 from harp-tech/gl-dev
Add support for parsing payload spec members
2 parents 4db09e9 + b0ab179 commit 87b4934

1 file changed

Lines changed: 57 additions & 11 deletions

File tree

harp/reader.py

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import re
2+
from math import log2
23
from functools import partial
34
from pandas import DataFrame, Series
45
from typing import Iterable, Callable, Union
5-
from harp.model import BitMask, GroupMask, MaskValueItem, Model, Register
6+
from harp.model import BitMask, GroupMask, MaskValueItem, Model, PayloadMember, Register
67
from harp.io import read
78

89
_camel_to_snake_regex = re.compile(r"(?<!^)(?=[A-Z])")
@@ -40,10 +41,6 @@ def _id_camel_to_snake(id: str):
4041
return _camel_to_snake_regex.sub("_", id).lower()
4142

4243

43-
def _keys_camel_to_snake(keys: Iterable[str]):
44-
return [_id_camel_to_snake(k) for k in keys]
45-
46-
4744
def _create_bit_parser(mask: Union[int, MaskValueItem]):
4845
def parser(xs: Series) -> Series:
4946
return (xs & mask) != 0
@@ -63,12 +60,55 @@ def parser(df: DataFrame):
6360
return parser
6461

6562

63+
def _create_groupmask_lookup(groupMask: GroupMask):
64+
return {v.root: n for n, v in groupMask.values.items()}
65+
66+
6667
def _create_groupmask_parser(name: str, groupMask: GroupMask):
67-
name = _id_camel_to_snake(name)
68-
lookup = {v.root: n for n, v in groupMask.values.items()}
68+
lookup = _create_groupmask_lookup(groupMask)
6969

7070
def parser(df: DataFrame):
71-
return DataFrame({name: df.map(lambda x: lookup[x])})
71+
return DataFrame({name: df[0].map(lookup)})
72+
73+
return parser
74+
75+
76+
def _mask_shift(mask: int):
77+
lsb = mask & (~mask + 1)
78+
return int(log2(lsb))
79+
80+
81+
def _create_payloadmember_parser(device: Model, member: PayloadMember):
82+
offset = member.offset
83+
if offset is None:
84+
offset = 0
85+
86+
shift = None
87+
if member.mask is not None:
88+
shift = _mask_shift(member.mask)
89+
90+
lookup = None
91+
if member.maskType is not None:
92+
key = member.maskType.root
93+
groupMask = device.groupMasks.get(key)
94+
if groupMask is not None:
95+
lookup = _create_groupmask_lookup(groupMask)
96+
97+
is_boolean = False
98+
if member.interfaceType is not None:
99+
is_boolean = member.interfaceType.root == "bool"
100+
101+
def parser(df: DataFrame):
102+
series = df[offset]
103+
if member.mask is not None:
104+
series = series & member.mask
105+
if shift > 0:
106+
series = Series(series.values >> shift, series.index)
107+
if is_boolean:
108+
series = series != 0
109+
elif lookup is not None:
110+
series = series.map(lookup)
111+
return series
72112

73113
return parser
74114

@@ -92,9 +132,15 @@ def _create_register_reader(device: Model, name: str):
92132
return RegisterReader(register, reader)
93133

94134
if register.payloadSpec is not None:
95-
columns = register.payloadSpec.keys()
96-
columns = _keys_camel_to_snake(columns)
97-
reader = partial(reader, columns=columns)
135+
payload_parsers = [
136+
(_id_camel_to_snake(key), _create_payloadmember_parser(device, member))
137+
for key, member in register.payloadSpec.items()
138+
]
139+
140+
def parser(df: DataFrame):
141+
return DataFrame({n: f(df) for n, f in payload_parsers}, index=df.index)
142+
143+
reader = _compose(parser, reader)
98144
return RegisterReader(register, reader)
99145

100146
columns = [_id_camel_to_snake(name)]

0 commit comments

Comments
 (0)