77from functools import partial
88from numpy import dtype
99from pandas import DataFrame , Series
10- from typing import Any , BinaryIO , Iterable , Optional , Protocol , Union
10+ from typing import Any , BinaryIO , Callable , Iterable , Optional , Protocol , Union
1111from pandas ._typing import Axes
1212from harp .model import BitMask , GroupMask , Model , PayloadMember , Register
1313from harp .io import read
@@ -21,6 +21,7 @@ def __call__(
2121 self ,
2222 file : Optional [Union [str , bytes , PathLike [Any ], BinaryIO ]] = None ,
2323 epoch : Optional [datetime ] = None ,
24+ keep_type : bool = False ,
2425 ) -> DataFrame :
2526 ...
2627
@@ -53,8 +54,23 @@ def __getattr__(self, __name: str) -> RegisterReader:
5354 return self .registers [__name ]
5455
5556
56- def _compose (f , g ):
57- return lambda * a , ** kw : f (g (* a , ** kw ))
57+ def _compose_parser (
58+ f : Callable [[DataFrame ], DataFrame ], g : Callable [..., DataFrame ]
59+ ) -> Callable [..., DataFrame ]:
60+ def parser (
61+ file : Optional [Union [str , bytes , PathLike [Any ], BinaryIO ]] = None ,
62+ columns : Optional [Axes ] = None ,
63+ epoch : Optional [datetime ] = None ,
64+ keep_type : bool = False ,
65+ ):
66+ df = g (file , columns , epoch , keep_type )
67+ result = f (df )
68+ type_col = df .get ("type" )
69+ if type_col is not None :
70+ result ["type" ] = type_col
71+ return result
72+
73+ return parser
5874
5975
6076def _id_camel_to_snake (id : str ):
@@ -138,6 +154,7 @@ def reader(
138154 file : Optional [Union [str , bytes , PathLike [Any ], BinaryIO ]] = None ,
139155 columns : Optional [Axes ] = None ,
140156 epoch : Optional [datetime ] = None ,
157+ keep_type : bool = False ,
141158 ):
142159 if file is None :
143160 file = f"{ base_path } _{ register .address } .bin"
@@ -149,6 +166,7 @@ def reader(
149166 length = register .length ,
150167 columns = columns ,
151168 epoch = epoch ,
169+ keep_type = keep_type ,
152170 )
153171 return data
154172
@@ -164,13 +182,13 @@ def _create_register_parser(device: Model, name: str, base_path: Path):
164182 bitMask = None if device .bitMasks is None else device .bitMasks .get (key )
165183 if bitMask is not None :
166184 parser = _create_bitmask_parser (bitMask )
167- reader = _compose (parser , reader )
185+ reader = _compose_parser (parser , reader )
168186 return RegisterReader (register , reader )
169187
170188 groupMask = None if device .groupMasks is None else device .groupMasks .get (key )
171189 if groupMask is not None :
172190 parser = _create_groupmask_parser (name , groupMask )
173- reader = _compose (parser , reader )
191+ reader = _compose_parser (parser , reader )
174192 return RegisterReader (register , reader )
175193
176194 if register .payloadSpec is not None :
@@ -182,7 +200,7 @@ def _create_register_parser(device: Model, name: str, base_path: Path):
182200 def parser (df : DataFrame ):
183201 return DataFrame ({n : f (df ) for n , f in payload_parsers }, index = df .index )
184202
185- reader = _compose (parser , reader )
203+ reader = _compose_parser (parser , reader )
186204 return RegisterReader (register , reader )
187205
188206 columns = [_id_camel_to_snake (name )]
0 commit comments