1
1
import csv
2
2
from dataclasses import dataclass
3
3
from enum import Enum
4
+ from typing import Union
4
5
from defs .common import strtoint
5
6
import itertools
6
7
import json
@@ -22,6 +23,8 @@ class Data_Type(Enum):
22
23
'''32 bit signed int'''
23
24
_16BIT_FLAGS = 7
24
25
_8BIT_FLAGS = 8
26
+ _32BIT_FLAGS = 9
27
+
25
28
26
29
ASCII = 84
27
30
''' 2 characters '''
@@ -104,7 +107,9 @@ def getSize(cls, data_type : 'Data_Type'):
104
107
Data_Type .UINT : 32 ,
105
108
Data_Type .SHORT : 16 ,
106
109
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
108
113
}
109
114
110
115
if data_type in sizes :
@@ -143,6 +148,7 @@ def fromString(cls, name : str):
143
148
"READDISABLED" : "READDISABLED" ,
144
149
"DISABLED" : "READDISABLED" ,
145
150
"D" : "READDISABLED" ,
151
+ "R/W" : "WRITE" ,
146
152
"RW" : "WRITE" ,
147
153
"W" : "WRITE" ,
148
154
"YES" : "WRITE"
@@ -337,7 +343,7 @@ def determine_delimiter(first_row) -> str:
337
343
if first_row .count (';' ) < first_row .count (',' ):
338
344
delimeter = ','
339
345
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
341
347
342
348
csvfile = itertools .chain ([first_row ], csvfile ) #add clean header to begining of iterator
343
349
@@ -357,7 +363,7 @@ def determine_delimiter(first_row) -> str:
357
363
character_part = row ['unit' ]
358
364
else :
359
365
# 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' ])
361
367
362
368
# Iterate over the matches and assign them to appropriate variables
363
369
for match in matches :
@@ -373,7 +379,7 @@ def determine_delimiter(first_row) -> str:
373
379
variable_name = row ['variable name' ] if row ['variable name' ] else row ['documented name' ]
374
380
variable_name = variable_name = variable_name .strip ().lower ().replace (' ' , '_' ).replace ('__' , '_' ) #clean name
375
381
376
- if re .search ("[^a-zA-Z0-9\_]" , variable_name ) :
382
+ if re .search (r "[^a-zA-Z0-9\_]" , variable_name ) :
377
383
print ("WARNING Invalid Name : " + str (variable_name ) + " reg: " + str (row ['register' ]) + " doc name: " + str (row ['documented name' ]) + " path: " + str (path ))
378
384
379
385
#convert to float
@@ -659,15 +665,21 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma
659
665
value = int .from_bytes (register [:2 ], byteorder = 'big' , signed = False )
660
666
elif entry .data_type == Data_Type .SHORT :
661
667
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 :
663
669
#16 bit flags
664
670
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
667
679
668
680
if entry .documented_name + '_codes' in self .protocolSettings .codes :
669
681
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)
671
683
byte = i // 8
672
684
bit = i % 8
673
685
val = register [byte ]
@@ -680,7 +692,7 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma
680
692
value = "," .join (flags )
681
693
else :
682
694
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)
684
696
# Check if the i-th bit is set
685
697
if (val >> i ) & 1 :
686
698
flags .append ("1" )
@@ -762,32 +774,58 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma
762
774
value = - value
763
775
#value = struct.unpack('<h', bytes([min(max(registry[item.register], 0), 255), min(max(registry[item.register+1], 0), 255)]))[0]
764
776
#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
+
767
779
#16 bit flags
768
780
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 ]
771
800
772
801
if entry .documented_name + '_codes' in self .codes :
773
802
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
+
780
814
781
815
value = "," .join (flags )
782
816
else :
783
817
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
+
790
827
value = '' .join (flags )
828
+
791
829
elif entry .data_type .value > 200 or entry .data_type == Data_Type .BYTE : #bit types
792
830
bit_size = Data_Type .getSize (entry .data_type )
793
831
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
823
861
824
862
return value
825
863
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 ]:
827
865
'''process registry into appropriate datatypes and names -- maybe add func for single entry later?'''
828
866
829
867
concatenate_registry : dict = {}
@@ -856,6 +894,10 @@ def process_registery(self, registry : dict[int,int] | dict[int,bytes] , map : l
856
894
concatenated_value = concatenated_value + str (concatenate_registry [key ])
857
895
del concatenate_registry [key ]
858
896
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
+
859
901
info [entry .variable_name ] = concatenated_value
860
902
else :
861
903
info [entry .variable_name ] = value
@@ -871,7 +913,7 @@ def validate_registry_entry(self, entry : registry_map_entry, val) -> int:
871
913
return 0
872
914
873
915
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
875
917
if entry .value_regex : #regex validation
876
918
if re .match (entry .value_regex , val ):
877
919
if entry .concatenate :
0 commit comments