33from math import log2
44from os import PathLike
55from pathlib import Path
6+ from datetime import datetime
67from functools import partial
78from numpy import dtype
89from pandas import DataFrame , Series
9- from typing import Any , BinaryIO , Iterable , Optional , Protocol , Union
10+ from typing import Any , BinaryIO , Callable , Iterable , Optional , Protocol , Union
1011from pandas ._typing import Axes
1112from harp .model import BitMask , GroupMask , Model , PayloadMember , Register
1213from harp .io import read
1718
1819class _ReadRegister (Protocol ):
1920 def __call__ (
20- self , file : Optional [Union [str , bytes , PathLike [Any ], BinaryIO ]] = None
21+ self ,
22+ file : Optional [Union [str , bytes , PathLike [Any ], BinaryIO ]] = None ,
23+ epoch : Optional [datetime ] = None ,
24+ keep_type : bool = False ,
2125 ) -> DataFrame :
2226 ...
2327
@@ -50,8 +54,23 @@ def __getattr__(self, __name: str) -> RegisterReader:
5054 return self .registers [__name ]
5155
5256
53- def _compose (f , g ):
54- 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
5574
5675
5776def _id_camel_to_snake (id : str ):
@@ -134,6 +153,8 @@ def _create_register_reader(register: Register, base_path: Path):
134153 def reader (
135154 file : Optional [Union [str , bytes , PathLike [Any ], BinaryIO ]] = None ,
136155 columns : Optional [Axes ] = None ,
156+ epoch : Optional [datetime ] = None ,
157+ keep_type : bool = False ,
137158 ):
138159 if file is None :
139160 file = f"{ base_path } _{ register .address } .bin"
@@ -144,6 +165,8 @@ def reader(
144165 dtype = dtype (register .type ),
145166 length = register .length ,
146167 columns = columns ,
168+ epoch = epoch ,
169+ keep_type = keep_type ,
147170 )
148171 return data
149172
@@ -159,13 +182,13 @@ def _create_register_parser(device: Model, name: str, base_path: Path):
159182 bitMask = None if device .bitMasks is None else device .bitMasks .get (key )
160183 if bitMask is not None :
161184 parser = _create_bitmask_parser (bitMask )
162- reader = _compose (parser , reader )
185+ reader = _compose_parser (parser , reader )
163186 return RegisterReader (register , reader )
164187
165188 groupMask = None if device .groupMasks is None else device .groupMasks .get (key )
166189 if groupMask is not None :
167190 parser = _create_groupmask_parser (name , groupMask )
168- reader = _compose (parser , reader )
191+ reader = _compose_parser (parser , reader )
169192 return RegisterReader (register , reader )
170193
171194 if register .payloadSpec is not None :
@@ -177,7 +200,7 @@ def _create_register_parser(device: Model, name: str, base_path: Path):
177200 def parser (df : DataFrame ):
178201 return DataFrame ({n : f (df ) for n , f in payload_parsers }, index = df .index )
179202
180- reader = _compose (parser , reader )
203+ reader = _compose_parser (parser , reader )
181204 return RegisterReader (register , reader )
182205
183206 columns = [_id_camel_to_snake (name )]
0 commit comments