11import csv
22from dataclasses import dataclass
33from enum import Enum
4+ from typing import Union
45from defs .common import strtoint
56import itertools
67import json
@@ -22,6 +23,8 @@ class Data_Type(Enum):
2223 '''32 bit signed int'''
2324 _16BIT_FLAGS = 7
2425 _8BIT_FLAGS = 8
26+ _32BIT_FLAGS = 9
27+
2528
2629 ASCII = 84
2730 ''' 2 characters '''
@@ -104,7 +107,9 @@ def getSize(cls, data_type : 'Data_Type'):
104107 Data_Type .UINT : 32 ,
105108 Data_Type .SHORT : 16 ,
106109 Data_Type .INT : 32 ,
107- Data_Type ._16BIT_FLAGS : 16
110+ Data_Type ._8BIT_FLAGS : 8 ,
111+ Data_Type ._16BIT_FLAGS : 16 ,
112+ Data_Type ._32BIT_FLAGS : 32
108113 }
109114
110115 if data_type in sizes :
@@ -143,6 +148,7 @@ def fromString(cls, name : str):
143148 "READDISABLED" : "READDISABLED" ,
144149 "DISABLED" : "READDISABLED" ,
145150 "D" : "READDISABLED" ,
151+ "R/W" : "WRITE" ,
146152 "RW" : "WRITE" ,
147153 "W" : "WRITE" ,
148154 "YES" : "WRITE"
@@ -337,7 +343,7 @@ def determine_delimiter(first_row) -> str:
337343 if first_row .count (';' ) < first_row .count (',' ):
338344 delimeter = ','
339345
340- first_row = re .sub (r"\s+" + re .escape (delimeter ) + "|" + re .escape (delimeter ) + "\s+" , delimeter , first_row ) #trim values
346+ first_row = re .sub (r"\s+" + re .escape (delimeter ) + "|" + re .escape (delimeter ) + r "\s+" , delimeter , first_row ) #trim values
341347
342348 csvfile = itertools .chain ([first_row ], csvfile ) #add clean header to begining of iterator
343349
@@ -357,7 +363,7 @@ def determine_delimiter(first_row) -> str:
357363 character_part = row ['unit' ]
358364 else :
359365 # Use regular expressions to extract numeric and character parts
360- matches = re .findall (r'([0-9.]+)|(.*?)$' , row ['unit' ])
366+ matches = re .findall (r'(\-? [0-9.]+)|(.*?)$' , row ['unit' ])
361367
362368 # Iterate over the matches and assign them to appropriate variables
363369 for match in matches :
@@ -373,7 +379,7 @@ def determine_delimiter(first_row) -> str:
373379 variable_name = row ['variable name' ] if row ['variable name' ] else row ['documented name' ]
374380 variable_name = variable_name = variable_name .strip ().lower ().replace (' ' , '_' ).replace ('__' , '_' ) #clean name
375381
376- if re .search ("[^a-zA-Z0-9\_]" , variable_name ) :
382+ if re .search (r "[^a-zA-Z0-9\_]" , variable_name ) :
377383 print ("WARNING Invalid Name : " + str (variable_name ) + " reg: " + str (row ['register' ]) + " doc name: " + str (row ['documented name' ]) + " path: " + str (path ))
378384
379385 #convert to float
@@ -659,15 +665,21 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma
659665 value = int .from_bytes (register [:2 ], byteorder = 'big' , signed = False )
660666 elif entry .data_type == Data_Type .SHORT :
661667 value = int .from_bytes (register [:2 ], byteorder = 'big' , signed = True )
662- elif entry .data_type == Data_Type ._16BIT_FLAGS or entry .data_type == Data_Type ._8BIT_FLAGS :
668+ elif entry .data_type == Data_Type ._16BIT_FLAGS or entry .data_type == Data_Type ._8BIT_FLAGS or entry . data_type == Data_Type . _32BIT_FLAGS :
663669 #16 bit flags
664670 start_bit : int = 0
665- if entry .data_type == Data_Type ._8BIT_FLAGS :
666- start_bit = 8
671+ end_bit : int = 16 #default 16 bit
672+ flag_size : int = Data_Type .getSize (entry .data_type )
673+
674+ if entry .register_bit > 0 : #handle custom bit offset
675+ start_bit = entry .register_bit
676+
677+ #handle custom sizes, less than 1 register
678+ end_bit = flag_size + start_bit
667679
668680 if entry .documented_name + '_codes' in self .protocolSettings .codes :
669681 flags : list [str ] = []
670- for i in range (start_bit , 16 ): # Iterate over each bit position (0 to 15)
682+ for i in range (start_bit , end_bit ): # Iterate over each bit position (0 to 15)
671683 byte = i // 8
672684 bit = i % 8
673685 val = register [byte ]
@@ -680,7 +692,7 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma
680692 value = "," .join (flags )
681693 else :
682694 flags : list [str ] = []
683- for i in range (start_bit , 16 ): # Iterate over each bit position (0 to 15)
695+ for i in range (start_bit , end_bit ): # Iterate over each bit position (0 to 15)
684696 # Check if the i-th bit is set
685697 if (val >> i ) & 1 :
686698 flags .append ("1" )
@@ -762,32 +774,58 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma
762774 value = - value
763775 #value = struct.unpack('<h', bytes([min(max(registry[item.register], 0), 255), min(max(registry[item.register+1], 0), 255)]))[0]
764776 #value = int.from_bytes(bytes([registry[item.register], registry[item.register + 1]]), byteorder='little', signed=True)
765- elif entry .data_type == Data_Type ._16BIT_FLAGS or entry .data_type == Data_Type ._8BIT_FLAGS :
766- val = registry [ entry . register ]
777+ elif entry .data_type == Data_Type ._16BIT_FLAGS or entry .data_type == Data_Type ._8BIT_FLAGS or entry . data_type == Data_Type . _32BIT_FLAGS :
778+
767779 #16 bit flags
768780 start_bit : int = 0
769- if entry .data_type == Data_Type ._8BIT_FLAGS :
770- start_bit = 8
781+ end_bit : int = 16 #default 16 bit
782+ flag_size : int = Data_Type .getSize (entry .data_type )
783+
784+ if entry .register_bit > 0 : #handle custom bit offset
785+ start_bit = entry .register_bit
786+
787+ #handle custom sizes, less than 1 register
788+ end_bit = flag_size + start_bit
789+
790+ offset : int = 0
791+ #calculate current offset for mutliregiter values, were assuming concatenate registers is in order, 0 being the first / lowest
792+ #offset should always be >= 0
793+ if entry .concatenate :
794+ offset : int = entry .register - entry .concatenate_registers [0 ]
795+
796+ #compensate for current offset
797+ end_bit = end_bit - (offset * 16 )
798+
799+ val = registry [entry .register ]
771800
772801 if entry .documented_name + '_codes' in self .codes :
773802 flags : list [str ] = []
774- for i in range (start_bit , 16 ): # Iterate over each bit position (0 to 15)
775- # Check if the i-th bit is set
776- if (val >> i ) & 1 :
777- flag_index = "b" + str (i )
778- if flag_index in self .codes [entry .documented_name + '_codes' ]:
779- flags .append (self .codes [entry .documented_name + '_codes' ][flag_index ])
803+ offset : int = 0
804+
805+ if end_bit > 0 :
806+ end : int = 16 if end_bit >= 16 else end_bit
807+ for i in range (start_bit , end ): # Iterate over each bit position (0 to 15)
808+ # Check if the i-th bit is set
809+ if (val >> i ) & 1 :
810+ flag_index = "b" + str (i + offset )
811+ if flag_index in self .codes [entry .documented_name + '_codes' ]:
812+ flags .append (self .codes [entry .documented_name + '_codes' ][flag_index ])
813+
780814
781815 value = "," .join (flags )
782816 else :
783817 flags : list [str ] = []
784- for i in range (start_bit , 16 ): # Iterate over each bit position (0 to 15)
785- # Check if the i-th bit is set
786- if (val >> i ) & 1 :
787- flags .append ("1" )
788- else :
789- flags .append ("0" )
818+ if end_bit > 0 :
819+ end : int = 16 if end_bit >= 16 else end_bit
820+ for i in range (start_bit , end ): # Iterate over each bit position (0 to 15)
821+ # Check if the i-th bit is set
822+ if (val >> i ) & 1 :
823+ flags .append ("1" )
824+ else :
825+ flags .append ("0" )
826+
790827 value = '' .join (flags )
828+
791829 elif entry .data_type .value > 200 or entry .data_type == Data_Type .BYTE : #bit types
792830 bit_size = Data_Type .getSize (entry .data_type )
793831 bit_mask = (1 << bit_size ) - 1 # Create a mask for extracting X bits
@@ -823,7 +861,7 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma
823861
824862 return value
825863
826- def process_registery (self , registry : dict [int ,int ] | dict [int ,bytes ] , map : list [registry_map_entry ]) -> dict [str ,str ]:
864+ def process_registery (self , registry : Union [ dict [int , int ], dict [int , bytes ] ] , map : list [registry_map_entry ]) -> dict [str ,str ]:
827865 '''process registry into appropriate datatypes and names -- maybe add func for single entry later?'''
828866
829867 concatenate_registry : dict = {}
@@ -856,6 +894,10 @@ def process_registery(self, registry : dict[int,int] | dict[int,bytes] , map : l
856894 concatenated_value = concatenated_value + str (concatenate_registry [key ])
857895 del concatenate_registry [key ]
858896
897+ #replace null characters with spaces and trim
898+ if entry .data_type == Data_Type .ASCII :
899+ concatenated_value = concatenated_value .replace ("\x00 " , " " ).strip ()
900+
859901 info [entry .variable_name ] = concatenated_value
860902 else :
861903 info [entry .variable_name ] = value
@@ -871,7 +913,7 @@ def validate_registry_entry(self, entry : registry_map_entry, val) -> int:
871913 return 0
872914
873915 if entry .data_type == Data_Type .ASCII :
874- if val and not re .match ('[^a-zA-Z0-9\_\-]' , val ): #validate ascii
916+ if val and not re .match (r '[^a-zA-Z0-9\_\-]' , val ): #validate ascii
875917 if entry .value_regex : #regex validation
876918 if re .match (entry .value_regex , val ):
877919 if entry .concatenate :
0 commit comments