77class ModbusFrame :
88 def __init__ (
99 self ,
10- func_code = 0 ,
11- register = None ,
12- fr_type = "request" ,
13- length = None ,
14- data = None ,
15- error_code = None ,
16- ):
10+ func_code : int = 0 ,
11+ register : int = None ,
12+ fr_type : str = "request" ,
13+ length : int = None ,
14+ data : bytearray = None ,
15+ error_code : int = None ,
16+ ) -> None :
1717 """Init a generic modbus frame.
1818
19- Args:
20- func_code (int, optional): Function Code. Defaults to 0.
21- register (int, optional): Register. Defaults to None.
22- fr_type (str, optional): Type of Frame (request or response).
23- Defaults to "request".
24- length (int, optional): Number of registers. Defaults to None.
25- data (bytearray, optional): Data. Defaults to None.
26- error_code (int, optional): Error Code. Defaults to None.
19+ :param int func_code: Function code (1-6,15,16). Defaults to 0.
20+ :param register: Register. Defaults to None.
21+ :type register: int or None
22+ :param fr_type: Frame type (request/response). Defaults to "request".
23+ :type fr_type: str or None
24+ :param length: Length of requested data. Defaults to None.
25+ :type length: int or None
26+ :param data: Payload. Defaults to None.
27+ :type data: bytearray or None
28+ :param error_code: Error Code. Defaults to None.
29+ :type error_code: int or None
30+
2731 """
2832
2933 self .type = fr_type
@@ -108,7 +112,7 @@ def __init__(
108112 self .pdu = None
109113 self .frame = None
110114
111- def _create_pdu (self ):
115+ def _create_pdu (self ) -> None :
112116 self .pdu = bytearray ([])
113117 self .pdu += bytearray ([self .func_code ])
114118
@@ -133,40 +137,40 @@ def _create_pdu(self):
133137 if self .func_code in [0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x8F , 0x90 ]:
134138 self .pdu += bytearray ([self .error_code ])
135139
136- def _create_frame (self ):
140+ def _create_frame (self ) -> None :
137141 """Override in derived Class"""
138142 pass
139143
140- def get_frame (self ):
144+ def get_frame (self ) -> bytearray :
141145 if self .frame is None :
142146 self ._create_frame ()
143147 return self .frame
144148
145149
146150class ModbusRTUFrame (ModbusFrame ):
147- def __init__ (self , device_addr = 0 , verbose : bool = False , * args , ** kwargs ):
151+ def __init__ (self , device_addr : int = 0 , verbose : bool = False , * args , ** kwargs ) -> None :
148152 """Create modbus rtu frame.
149153
150- Args:
151- device_addr (int, optional): Slave address . Defaults to 0 .
152- func_code ( int, optional) : Function code (1-6,15,16). Defaults to 0.
153- register ([type], optional) : Register. Defaults to None.
154- fr_type ( str, optional) : Frame type (request/response). Defaults to "request".
155- length ([type], optional) : Length of reqested data. Defaults to None.
156- data ([type], optional) : Payload. Defaults to None.
154+ :param int device_addr: Slave address. Defaults to 0.
155+ :param bool verbose: If True, print debug information . Defaults to False .
156+ :param int func_code : Function code (1-6,15,16). Defaults to 0.
157+ :param int register: Register. Defaults to None.
158+ :param str fr_type : Frame type (request/response). Defaults to "request".
159+ :param int length: Length of requested data. Defaults to None.
160+ :param bytes data: Payload. Defaults to None.
157161 """
158162 super (ModbusRTUFrame , self ).__init__ (* args , ** kwargs )
159163 self ._verbose = verbose
160164 self .device_addr = device_addr
161165 self .frame = None
162166
163- def _create_frame (self ):
167+ def _create_frame (self ) -> None :
164168 self ._create_pdu ()
165169 self .frame = bytearray ([self .device_addr ]) + self .pdu
166170 crc = ModbusRTUFrame ._crc16 (self .frame )
167171 self .frame += bytearray ([crc & 0xFF , crc >> 8 ])
168172
169- def __str__ (self ):
173+ def __str__ (self ) -> str :
170174 return "<ModbusRTUFrame ({}): device: {}, func_code: {}, frame:{}>" .format (
171175 self .type ,
172176 self .device_addr ,
@@ -175,7 +179,7 @@ def __str__(self):
175179 )
176180
177181 @classmethod
178- def _crc16 (cls , data ) :
182+ def _crc16 (cls , data : bytearray ) -> int :
179183 offset = 0
180184 length = len (data )
181185 if data is None or offset < 0 or offset > len (data ) - 1 and offset + length > len (data ):
@@ -191,15 +195,18 @@ def _crc16(cls, data):
191195 return crc
192196
193197 @classmethod
194- def parse_frame (cls , frame , fr_type = None , verbose = False ):
195- """Factory Method: Create a ModbusRTUFrame from bytearray.
196-
197- Args:
198- frame (bytearray): frame to parse.
199- fr_type (str, optional): request, response, or None
200-
201- Returns:
202- ModbusRTUFrame: parsed frame
198+ def parse_frame (
199+ cls , frame : bytearray , fr_type : str = None , verbose : bool = False
200+ ) -> "ModbusRTUFrame" :
201+ """Create a ModbusRTUFrame from bytearray.
202+
203+ :param bytearray frame: The frame to parse.
204+ :param str fr_type: Type of frame, either "request", "response", or
205+ None. If None, it will try to determine the type
206+ automatically.
207+ :param bool verbose: If True, print debug information.
208+ :return: ModbusRTUFrame object if parsing was successful, None otherwise.
209+ :rtype: ModbusRTUFrame or None
203210 """
204211
205212 verbose and print ("Parsing RTU frame: " + " " .join (["{:02x}" .format (x ) for x in frame ]))
@@ -278,15 +285,14 @@ def parse_frame(cls, frame, fr_type=None, verbose=False):
278285 # raise ValueError("Could not parse Frame " + " ".join(["{:02x}".format(x) for x in frame]))
279286
280287 @classmethod
281- def _check_both (cls , frame ) :
282- """Parser-Helper: if func_code is 0x05 or 0x06, we can't decide if it is a
283- request or a response. This method checks, if is a valid 0x05- or 0x06-frame.
288+ def _check_both (cls , frame : bytearray ) -> bool :
289+ """if func_code is 0x05 or 0x06, we can't decide if it is a request or a
290+ response. This method checks, if is a valid 0x05- or 0x06-frame.
284291
285- Args:
286- frame (bytearray): The frame to check.
292+ :param bytearray frame: The frame to check.
287293
288- Returns:
289- bool: True, if it is a valid 0x05- or 0x06-frame.
294+ :return: True, if it is a valid 0x05- or 0x06-frame.
295+ :rtype: bool
290296 """
291297 try :
292298 func_code = frame [1 ]
@@ -297,15 +303,13 @@ def _check_both(cls, frame):
297303 return False
298304
299305 @classmethod
300- def _check_request (cls , frame ) :
301- """Parser-Helper: This method checks, if is a valid request. It returns False,
306+ def _check_request (cls , frame : bytearray ) -> bool :
307+ """This method checks, if is a valid request. It returns False,
302308 if the frame could be a request or a response.
303309
304- Args:
305- frame (bytearray): The frame to check.
306-
307- Returns:
308- bool: True, if it is a valid request.
310+ :param bytearray frame: The frame to check.
311+ :return: True, if it is a valid request.
312+ :rtype: bool
309313 """
310314 try :
311315 func_code = frame [1 ]
@@ -321,15 +325,13 @@ def _check_request(cls, frame):
321325 return False
322326
323327 @classmethod
324- def _check_response (cls , frame ) :
325- """Parser-Helper: This method checks, if is a valid response. It returns False,
328+ def _check_response (cls , frame : bytearray ) -> bool :
329+ """This method checks, if is a valid response. It returns False,
326330 if the frame could be a request or a response.
327331
328- Args:
329- frame (bytearray): The frame to check.
330-
331- Returns:
332- bool: True, if it is a valid response.
332+ :param bytearray frame: The frame to check.
333+ :return: True, if it is a valid response.
334+ :rtype: bool
333335 """
334336 try :
335337 func_code = frame [1 ]
@@ -345,14 +347,12 @@ def _check_response(cls, frame):
345347 return False
346348
347349 @classmethod
348- def transform_frame (cls , tcp_frame ) :
350+ def transform_frame (cls , tcp_frame : "ModbusTCPFrame" ) -> "ModbusRTUFrame" :
349351 """transform a tcp-frame to a rtu-frame and copy all data
350352
351- Args:
352- tcp_frame (ModbusTCPFrame): tcp-frame
353-
354- Returns:
355- ModbusRTUFrame
353+ :param ModbusTCPFrame tcp_frame: tcp-frame to transform
354+ :return: ModbusRTUFrame object with data from tcp_frame
355+ :rtype: ModbusRTUFrame
356356 """
357357 frame = ModbusRTUFrame ()
358358 frame .data = tcp_frame .data
@@ -365,24 +365,27 @@ def transform_frame(cls, tcp_frame):
365365
366366
367367class ModbusTCPFrame (ModbusFrame ):
368- def __init__ (self , transaction_id = 0 , unit_id = 0 , * args , ** kwargs ):
368+ def __init__ (self , transaction_id : int = 0 , unit_id : int = 0 , * args , ** kwargs ) -> None :
369369 """Create modbus tcp frame.
370370
371- Args:
372- transaction_id (int, optional): Transaction ID. Defaults to 0.
373- unit_id (int, optional): Unit address. Defaults to 0.
374- func_code (int, optional): Function code (1-6,15,16). Defaults to 0.
375- register ([type], optional): Register. Defaults to None.
376- fr_type (str, optional): Frame type (request/response). Defaults to "request".
377- length ([type], optional): Length of reqested data. Defaults to None.
378- data ([type], optional): Payload. Defaults to None.
371+ :param int transaction_id: Transaction ID. Defaults to 0.
372+ :param int unit_id: Unit address. Defaults to 0.
373+ :param int func_code: Function code (1-6,15,16). Defaults to 0.
374+ :param register: Register. Defaults to None.
375+ :type register: int or None
376+ :param fr_type: Frame type (request/response). Defaults to "request".
377+ :type fr_type: str or None
378+ :param length: Length of requested data. Defaults to None.
379+ :type length: int or None
380+ :param data: Payload. Defaults to None.
381+ :type data: bytearray or None
379382 """
380383 super (ModbusTCPFrame , self ).__init__ (* args , ** kwargs )
381384 self .transaction_id = transaction_id
382385 self .unit_id = unit_id
383386 self .frame = None
384387
385- def _create_frame (self ):
388+ def _create_frame (self ) -> None :
386389 self ._create_pdu ()
387390 self .frame = bytearray ([self .transaction_id >> 8 , self .transaction_id & 0xFF ])
388391 self .frame += bytearray ([0x00 , 0x00 ]) # Protocol ID
@@ -391,20 +394,19 @@ def _create_frame(self):
391394 self .frame += bytearray ([self .unit_id ])
392395 self .frame += self .pdu
393396
394- def __str__ (self ):
397+ def __str__ (self ) -> str :
395398 return "<ModbusTCPFrame ({}): func_code: {}, frame:{}>" .format (
396399 self .type , self .func_code , " " .join (["{:02x}" .format (x ) for x in self .get_frame ()])
397400 )
398401
399402 @classmethod
400- def parse_frame (cls , frame , verbose = False ):
401- """Factory Method: Create a ModbusTCPFrame from bytearray.
403+ def parse_frame (cls , frame : bytearray , verbose : bool = False ) -> "ModbusTCPFrame" :
404+ """Create a ModbusTCPFrame from bytearray.
402405
403- Args:
404- frame (bytearray): frame to parse.
405-
406- Returns:
407- ModbusTCPFrame: parsed frame
406+ :param bytearray frame: The frame to parse.
407+ :param bool verbose: If True, print debug information.
408+ :return: ModbusTCPFrame object if parsing was successful, None otherwise.
409+ :rtype: ModbusTCPFrame or None
408410 """
409411
410412 verbose and print ("Parsing TCP frame: " + " " .join (["{:02x}" .format (x ) for x in frame ]))
@@ -454,7 +456,7 @@ def parse_frame(cls, frame, verbose=False):
454456
455457 f = None
456458 if cls ._check_response (frame , length ):
457- verbose and print ("frame is request " )
459+ verbose and print ("frame is response " )
458460 if func_code in [0x01 , 0x02 , 0x03 , 0x04 ]:
459461 bc = frame [8 ]
460462 data = frame [9 : 9 + bc ]
@@ -492,15 +494,13 @@ def parse_frame(cls, frame, verbose=False):
492494 # raise ValueError("Could not parse Frame " + " ".join(["{:02x}".format(x) for x in frame]))
493495
494496 @classmethod
495- def _check_both (cls , frame , length ) :
496- """Parser-Helper: if func_code is 0x05 or 0x06, we can't decide if it is a
497+ def _check_both (cls , frame : bytearray , length : int ) -> bool :
498+ """if func_code is 0x05 or 0x06, we can't decide if it is a
497499 request or a response. This method checks, if is a valid 0x05- or 0x06-frame.
498500
499- Args:
500- frame (bytearray): The frame to check.
501-
502- Returns:
503- bool: True, if it is a valid 0x05- or 0x06-frame.
501+ :param bytearray frame: The frame to check.
502+ :returns: True, if it is a valid 0x05- or 0x06-frame.
503+ :rtype: bool
504504 """
505505 try :
506506 func_code = frame [7 ]
@@ -511,15 +511,13 @@ def _check_both(cls, frame, length):
511511 return False
512512
513513 @classmethod
514- def _check_request (cls , frame , length ) :
515- """Parser-Helper: This method checks, if is a valid request. It returns False,
514+ def _check_request (cls , frame : bytearray , length : int ) -> bool :
515+ """This method checks, if is a valid request. It returns False,
516516 if the frame could be a request or a response.
517517
518- Args:
519- frame (bytearray): The frame to check.
520-
521- Returns:
522- bool: True, if it is a valid request.
518+ :param bytearray frame: The frame to check.
519+ :returns: True, if it is a valid request.
520+ :rtype: bool
523521 """
524522 try :
525523 func_code = frame [7 ]
@@ -535,15 +533,13 @@ def _check_request(cls, frame, length):
535533 return False
536534
537535 @classmethod
538- def _check_response (cls , frame , length ) :
539- """Parser-Helper: This method checks, if is a valid response. It returns False,
536+ def _check_response (cls , frame : bytearray , length : int ) -> bool :
537+ """This method checks, if is a valid response. It returns False,
540538 if the frame could be a request or a response.
541539
542- Args:
543- frame (bytearray): The frame to check.
544-
545- Returns:
546- bool: True, if it is a valid response.
540+ :param bytearray frame: The frame to check.
541+ :returns: True, if it is a valid response.
542+ :rtype: bool
547543 """
548544 try :
549545 func_code = frame [7 ]
0 commit comments