55from pathlib import Path
66from datetime import datetime
77from functools import partial
8+ from dataclasses import dataclass
89from numpy import dtype
910from pandas import DataFrame , Series
1011from typing import Any , BinaryIO , Callable , Iterable , Optional , Protocol , Union
1617_camel_to_snake_regex = re .compile (r"(?<!^)(?=[A-Z])" )
1718
1819
20+ @dataclass
21+ class _ReaderParams :
22+ path : Path
23+ epoch : Optional [datetime ] = None
24+ keep_type : bool = False
25+
26+
1927class _ReadRegister (Protocol ):
2028 def __call__ (
2129 self ,
@@ -55,13 +63,15 @@ def __getattr__(self, __name: str) -> RegisterReader:
5563
5664
5765def _compose_parser (
58- f : Callable [[DataFrame ], DataFrame ], g : Callable [..., DataFrame ]
66+ f : Callable [[DataFrame ], DataFrame ],
67+ g : Callable [..., DataFrame ],
68+ params : _ReaderParams ,
5969) -> Callable [..., DataFrame ]:
6070 def parser (
6171 file : Optional [Union [str , bytes , PathLike [Any ], BinaryIO ]] = None ,
6272 columns : Optional [Axes ] = None ,
63- epoch : Optional [datetime ] = None ,
64- keep_type : bool = False ,
73+ epoch : Optional [datetime ] = params . epoch ,
74+ keep_type : bool = params . keep_type ,
6575 ):
6676 df = g (file , columns , epoch , keep_type )
6777 result = f (df )
@@ -149,15 +159,15 @@ def parser(df: DataFrame):
149159 return parser
150160
151161
152- def _create_register_reader (register : Register , base_path : Path ):
162+ def _create_register_reader (register : Register , params : _ReaderParams ):
153163 def reader (
154164 file : Optional [Union [str , bytes , PathLike [Any ], BinaryIO ]] = None ,
155165 columns : Optional [Axes ] = None ,
156- epoch : Optional [datetime ] = None ,
157- keep_type : bool = False ,
166+ epoch : Optional [datetime ] = params . epoch ,
167+ keep_type : bool = params . keep_type ,
158168 ):
159169 if file is None :
160- file = f"{ base_path } _{ register .address } .bin"
170+ file = f"{ params . path } _{ register .address } .bin"
161171
162172 data = read (
163173 file ,
@@ -173,22 +183,22 @@ def reader(
173183 return reader
174184
175185
176- def _create_register_parser (device : Model , name : str , base_path : Path ):
186+ def _create_register_parser (device : Model , name : str , params : _ReaderParams ):
177187 register = device .registers [name ]
178- reader = _create_register_reader (register , base_path )
188+ reader = _create_register_reader (register , params )
179189
180190 if register .maskType is not None :
181191 key = register .maskType .root
182192 bitMask = None if device .bitMasks is None else device .bitMasks .get (key )
183193 if bitMask is not None :
184194 parser = _create_bitmask_parser (bitMask )
185- reader = _compose_parser (parser , reader )
195+ reader = _compose_parser (parser , reader , params )
186196 return RegisterReader (register , reader )
187197
188198 groupMask = None if device .groupMasks is None else device .groupMasks .get (key )
189199 if groupMask is not None :
190200 parser = _create_groupmask_parser (name , groupMask )
191- reader = _compose_parser (parser , reader )
201+ reader = _compose_parser (parser , reader , params )
192202 return RegisterReader (register , reader )
193203
194204 if register .payloadSpec is not None :
@@ -200,7 +210,7 @@ def _create_register_parser(device: Model, name: str, base_path: Path):
200210 def parser (df : DataFrame ):
201211 return DataFrame ({n : f (df ) for n , f in payload_parsers }, index = df .index )
202212
203- reader = _compose_parser (parser , reader )
213+ reader = _compose_parser (parser , reader , params )
204214 return RegisterReader (register , reader )
205215
206216 columns = [_id_camel_to_snake (name )]
@@ -209,7 +219,10 @@ def parser(df: DataFrame):
209219
210220
211221def create_reader (
212- device : Union [str , PathLike , Model ], include_common_registers : bool = True
222+ device : Union [str , PathLike , Model ],
223+ include_common_registers : bool = True ,
224+ epoch : Optional [datetime ] = None ,
225+ keep_type : bool = False ,
213226):
214227 if isinstance (device , Model ):
215228 base_path = Path (device .device )
@@ -223,7 +236,9 @@ def create_reader(
223236 base_path = path / device .device if is_dir else path .parent / device .device
224237
225238 reg_readers = {
226- name : _create_register_parser (device , name , base_path )
239+ name : _create_register_parser (
240+ device , name , _ReaderParams (base_path , epoch , keep_type )
241+ )
227242 for name in device .registers .keys ()
228243 }
229244 return DeviceReader (device , reg_readers )
0 commit comments