From 48fc7d6c9549513d9b1da3f99f449fc7de27821f Mon Sep 17 00:00:00 2001
From: tao_z <tzj0429@163.com>
Date: Fri, 10 Jun 2022 19:23:26 +0800
Subject: [PATCH] 修改信息打印标准 增加数据写入功能

---
 dbc.py |  238 ++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 128 insertions(+), 110 deletions(-)

diff --git a/dbc.py b/dbc.py
index 9e7a470..3bb643a 100644
--- a/dbc.py
+++ b/dbc.py
@@ -22,8 +22,10 @@
 UNSIGNED = 0
 SIGNED = 1
 
+
 def normalizeValueTable(table):
     return {int(k): v for k, v in table.items()}
+
 
 @attr.s(cmp=False)
 class Frame:
@@ -73,7 +75,7 @@
             if sig.getStartbit() + int(sig.size) > maxBit:
                 maxBit = sig.getStartbit() + int(sig.size)
         self.size = max(self.size, int(math.ceil(maxBit / 8)))
-    
+
     def setFdType(self):
         """Try to guess and set the CAN type for every frame.
         If a Frame is longer than 8 bytes, it must be Flexible Data Rate frame (CAN-FD).
@@ -92,7 +94,7 @@
         bitfieldLe = []
         bitfieldBe = []
 
-        for i in range(0,64):
+        for i in range(0, 64):
             bitfieldBe.append(0)
             bitfieldLe.append(0)
             bitfield.append(0)
@@ -100,21 +102,21 @@
 
         for sig in self.signals:
             i += 1
-            for bit in range(sig.getStartbit(),  sig.getStartbit() + int(sig.size)):
+            for bit in range(sig.getStartbit(),
+                             sig.getStartbit() + int(sig.size)):
                 if sig.is_little_endian:
                     bitfieldLe[bit] = i
                 else:
                     bitfieldBe[bit] = i
 
-        for i in range(0,8):
-            for j in range(0,8):
-                bitfield[i*8+j] = bitfieldLe[i*8+(7-j)]
+        for i in range(0, 8):
+            for j in range(0, 8):
+                bitfield[i * 8 + j] = bitfieldLe[i * 8 + (7 - j)]
 
-        for i in range(0,8):
-            for j in range(0,8):
-                if bitfield[i*8+j] == 0:
-                    bitfield[i*8+j] = bitfieldBe[i*8+j]
-
+        for i in range(0, 8):
+            for j in range(0, 8):
+                if bitfield[i * 8 + j] == 0:
+                    bitfield[i * 8 + j] = bitfieldBe[i * 8 + j]
 
         return bitfield
 
@@ -143,48 +145,51 @@
     * _multiplex ('Multiplexor' or Number of Multiplex)
     """
 
-    name = attr.ib(default = "")
+    name = attr.ib(default="")
     #    float_factory = attr.ib(default=defaultFloatFactory)
     float_factory = defaultFloatFactory
     startBit = attr.ib(type=int, default=0)
-    size = attr.ib(type=int, default = 0)
-    is_little_endian = attr.ib(type=bool, default = True)
-    is_signed = attr.ib(type=bool, default = True)
-    offset = attr.ib(converter = float_factory, default = float_factory(0.0))
-    factor = attr.ib(converter = float_factory, default = float_factory(1.0))
+    size = attr.ib(type=int, default=0)
+    is_little_endian = attr.ib(type=bool, default=True)
+    is_signed = attr.ib(type=bool, default=True)
+    offset = attr.ib(converter=float_factory, default=float_factory(0.0))
+    factor = attr.ib(converter=float_factory, default=float_factory(1.0))
 
     #    offset = attr.ib(converter = float_factory, default = 0.0)
 
-    min  = attr.ib(converter=float_factory)
+    min = attr.ib(converter=float_factory)
+
     @min.default
     def setDefaultMin(self):
-        return  self.calcMin()
+        return self.calcMin()
 
-    max =  attr.ib(converter = float_factory)
+    max = attr.ib(converter=float_factory)
+
     @max.default
     def setDefaultMax(self):
-        return  self.calcMax()
+        return self.calcMax()
 
-    unit = attr.ib(type=str, default ="")
-    receiver = attr.ib(default = attr.Factory(list))
-    comment = attr.ib(default = None)
-    multiplex  = attr.ib(default = None)
+    unit = attr.ib(type=str, default="")
+    receiver = attr.ib(default=attr.Factory(list))
+    comment = attr.ib(default=None)
+    multiplex = attr.ib(default=None)
 
-    mux_value = attr.ib(default = None)
+    mux_value = attr.ib(default=None)
     is_float = attr.ib(type=bool, default=False)
-    enumeration = attr.ib(type=str, default = None)
-    comments = attr.ib(type=dict, default = attr.Factory(dict))
-    attributes = attr.ib(type=dict, default = attr.Factory(dict))
-    values = attr.ib(type=dict, converter=normalizeValueTable, default = attr.Factory(dict))
-    calc_min_for_none = attr.ib(type=bool, default = True)
-    calc_max_for_none = attr.ib(type=bool, default = True)
-    muxValMax = attr.ib(default = 0)
-    muxValMin = attr.ib(default = 0)
-    muxerForSignal= attr.ib(type=str, default = None)
+    enumeration = attr.ib(type=str, default=None)
+    comments = attr.ib(type=dict, default=attr.Factory(dict))
+    attributes = attr.ib(type=dict, default=attr.Factory(dict))
+    values = attr.ib(type=dict,
+                     converter=normalizeValueTable,
+                     default=attr.Factory(dict))
+    calc_min_for_none = attr.ib(type=bool, default=True)
+    calc_max_for_none = attr.ib(type=bool, default=True)
+    muxValMax = attr.ib(default=0)
+    muxValMin = attr.ib(default=0)
+    muxerForSignal = attr.ib(type=str, default=None)
 
     def __attrs_post_init__(self):
         self.multiplex = self.multiplexSetter(self.multiplex)
-
 
     @property
     def spn(self):
@@ -253,7 +258,8 @@
             startBitInternal = startBitInternal + self.size - 1
         # bit numbering not consistent with byte order. reverse
         if bitNumbering is not None and bitNumbering != self.is_little_endian:
-            startBitInternal = startBitInternal - (startBitInternal % 8) + 7 - (startBitInternal % 8)
+            startBitInternal = startBitInternal - (
+                startBitInternal % 8) + 7 - (startBitInternal % 8)
         return int(startBitInternal)
 
     def calculateRawRange(self):
@@ -261,7 +267,7 @@
         :return: Signal range, i.e. (0, 15) for unsigned 4 bit Signal or (-8, 7) for signed one.
         :rtype: tuple
         """
-        rawRange = 2 ** (self.size - (1 if self.is_signed else 0))
+        rawRange = 2**(self.size - (1 if self.is_signed else 0))
         return (self.float_factory(-rawRange if self.is_signed else 0),
                 self.float_factory(rawRange - 1))
 
@@ -304,15 +310,12 @@
                     value = value_key
                     break
             else:
-                raise ValueError(
-                        "{} is invalid value choice for {}".format(value, self)
-                )
+                raise ValueError("{} is invalid value choice for {}".format(
+                    value, self))
 
         if not (self.min <= value <= self.max):
-            print(
-                "Value {} is not valid for {}. Min={} and Max={}".format(
-                    value, self, self.min, self.max)
-                )
+            print("Value {} is not valid for {}. Min={} and Max={}".format(
+                value, self, self.min, self.max))
         raw_value = (value - self.offset) / self.factor
 
         if not self.is_float:
@@ -338,7 +341,9 @@
     def __str__(self):
         return self.name
 
+
 class DBC:
+
     def __init__(self, dbcfile=None):
         self.filePath = dbcfile
         self.frames = self.__load()
@@ -349,7 +354,7 @@
         frameList = []
         i = 0
         frame = None
-        with open(self.filePath, mode='r', encoding='gb2312') as f:
+        with open(self.filePath, mode='r', encoding=dbcImportEncoding) as f:
             for line in f.readlines():
                 i = i + 1
                 l = line.strip()
@@ -358,14 +363,14 @@
                 # logging.info(l)
                 if l.startswith('BO_ '):
                     # frames
-                    regexp = re.compile("^BO\_ ([^\ ]+) ([^\ ]+) *: ([^\ ]+) ([^\ ]+)")
+                    regexp = re.compile(
+                        "^BO\_ ([^\ ]+) ([^\ ]+) *: ([^\ ]+) ([^\ ]+)")
                     temp = regexp.match(l)
                     # name, id, dlc, transmitters
-                    frame = Frame(
-                        temp.group(2),
-                        id=int(temp.group(1)),
-                        size=int(temp.group(3)),
-                        transmitters=temp.group(4).split())
+                    frame = Frame(temp.group(2),
+                                  id=int(temp.group(1)),
+                                  size=int(temp.group(3)),
+                                  transmitters=temp.group(4).split())
                     frameList.append(frame)
                     pass
                 elif l.startswith('SG_ '):
@@ -375,30 +380,34 @@
                     temp = regexp.match(l)
                     if temp:
                         extras = {}
-                        receiver = list(map(str.strip, temp.group(11).split(',')))
-                        tempSig = Signal(
-                            temp.group(1),
-                            startBit=int(temp.group(2)),
-                            size=int(temp.group(3)),
-                            is_little_endian=(int(temp.group(4)) == 1),
-                            is_signed=(temp.group(5) == '-'),
-                            factor=temp.group(6),
-                            offset=temp.group(7),
-                            min=temp.group(8),
-                            max=temp.group(9),
-                            unit=temp.group(10),
-                            receiver=receiver,
-                            **extras
-                        )
+                        receiver = list(
+                            map(str.strip,
+                                temp.group(11).split(',')))
+                        tempSig = Signal(temp.group(1),
+                                         startBit=int(temp.group(2)),
+                                         size=int(temp.group(3)),
+                                         is_little_endian=(int(
+                                             temp.group(4)) == 1),
+                                         is_signed=(temp.group(5) == '-'),
+                                         factor=temp.group(6),
+                                         offset=temp.group(7),
+                                         min=temp.group(8),
+                                         max=temp.group(9),
+                                         unit=temp.group(10),
+                                         receiver=receiver,
+                                         **extras)
                         if not tempSig.is_little_endian:
                             # startbit of motorola coded signals are MSB in dbc
-                            tempSig.setStartbit(int(temp.group(2)), bitNumbering=1)
+                            tempSig.setStartbit(int(temp.group(2)),
+                                                bitNumbering=1)
                         frame.signals.append(tempSig)
                     else:
                         pattern = "^SG\_ +(\w+) +(\w+) *: *(\d+)\|(\d+)@(\d+)([\+|\-]) +\(([0-9.+\-eE]+),([0-9.+\-eE]+)\) +\[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] +\"(.*)\" +(.*)"
                         regexp = re.compile(pattern)
                         temp = regexp.match(l)
-                        receiver = list(map(str.strip, temp.group(12).split(',')))
+                        receiver = list(
+                            map(str.strip,
+                                temp.group(12).split(',')))
                         multiplex = temp.group(2)
 
                         is_complex_multiplexed = False
@@ -413,25 +422,24 @@
                             try:
                                 multiplex = int(multiplex[1:])
                             except:
-                                raise Exception('error decoding line',line)
+                                raise Exception('error decoding line', line)
 
                         extras = {}
 
-                        tempSig = Signal(
-                            temp.group(1),
-                            startBit=int(temp.group(3)),
-                            size=int(temp.group(4)),
-                            is_little_endian=(int(temp.group(5)) == 1),
-                            is_signed=(temp.group(6) == '-'),
-                            factor=temp.group(7),
-                            offset=temp.group(8),
-                            min=temp.group(9),
-                            max=temp.group(10),
-                            unit=temp(11),
-                            receiver=receiver,
-                            multiplex=multiplex,
-                            **extras
-                        )
+                        tempSig = Signal(temp.group(1),
+                                         startBit=int(temp.group(3)),
+                                         size=int(temp.group(4)),
+                                         is_little_endian=(int(
+                                             temp.group(5)) == 1),
+                                         is_signed=(temp.group(6) == '-'),
+                                         factor=temp.group(7),
+                                         offset=temp.group(8),
+                                         min=temp.group(9),
+                                         max=temp.group(10),
+                                         unit=temp(11),
+                                         receiver=receiver,
+                                         multiplex=multiplex,
+                                         **extras)
 
                         if is_complex_multiplexed:
                             tempSig.is_multiplexer = True
@@ -439,7 +447,8 @@
 
                         if not tempSig.is_little_endian:
                             # startbit of motorola coded signals are MSB in dbc
-                            tempSig.setStartbit(int(temp.group(3)), bitNumbering=1)
+                            tempSig.setStartbit(int(temp.group(3)),
+                                                bitNumbering=1)
                         frame.addSignal(tempSig)
 
                         if is_complex_multiplexed:
@@ -468,8 +477,10 @@
                         if testF.id == int(tmpId):
                             for signal in testF.signals:
                                 if signal.name == signalName:
-                                    for i in range(math.floor(len(tempList) / 2)):
-                                        signal.values[tempList[i * 2].strip()] = tempList[i * 2 + 1].strip()
+                                    for i in range(
+                                            math.floor(len(tempList) / 2)):
+                                        signal.values[tempList[i * 2].strip(
+                                        )] = tempList[i * 2 + 1].strip()
                                     break
                             break
                 elif l.startswith("VAL_TABLE_ "):
@@ -491,7 +502,8 @@
                     regexp = re.compile("^BA\_ +\"[A-Za-z0-9[\-_ .]+\" +(.+)")
                     tempba = regexp.match(l)
                     if tempba.group(1).strip().startswith("BO_ "):
-                        regexp = re.compile(r"^BA_ +\"(.*)\" +BO_ +(\w+) +(.+);")
+                        regexp = re.compile(
+                            r"^BA_ +\"(.*)\" +BO_ +(\w+) +(.+);")
                         temp = regexp.match(l)
                         tempId = temp.group(2)
                         for testF in frameList:
@@ -501,10 +513,12 @@
                             tempCys = temp.group(3)
                             frame.cycle = int(tempCys)
                 elif l.startswith("SIG_GROUP_ "):
-                    regexp = re.compile("^SIG\_GROUP\_ +(\w+) +(\w+) +(\w+) +\:(.*);")
+                    regexp = re.compile(
+                        "^SIG\_GROUP\_ +(\w+) +(\w+) +(\w+) +\:(.*);")
                     temp = regexp.match(l)
                 elif l.startswith("SIG_VALTYPE_ "):
-                    regexp = re.compile("^SIG\_VALTYPE\_ +(\w+) +(\w+)\s*\:(.*);")
+                    regexp = re.compile(
+                        "^SIG\_VALTYPE\_ +(\w+) +(\w+)\s*\:(.*);")
                     temp = regexp.match(l)
                 elif l.startswith("BA_DEF_DEF_ "):
                     pattern = "^BA\_DEF\_DEF\_ +\"([A-Za-z0-9\-_\.]+)\" +(.+)\;"
@@ -516,7 +530,7 @@
                     pattern = "^EV_ +([A-Za-z0-9\-_]+) *\: +([0-9]+) +\[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] +\"(\w*)\" +([0-9.+\-eE]+) +([0-9.+\-eE]+) +([A-Za-z0-9\-_]+) +(.*);"
                     regexp = re.compile(pattern)
                     temp = regexp.match(l)
-                
+
         return frameList
 
     def __setFdType(self):
@@ -527,13 +541,13 @@
         for frame in self.frames:
             # if frame.size == 0:
             frame.calcDLC()
-            print(frame.id, frame.size)
+            # print(frame.id, frame.size)
             if frame.size > 8:
                 frame.is_fd = True
-    
+
     def __setExtended(self):
         for frame in self.frames:
-        # extended-flag is implicite in canid, thus repair this:
+            # extended-flag is implicite in canid, thus repair this:
             if frame.id > 0x80000000:
                 frame.id -= 0x80000000
                 frame.extended = 1
@@ -565,37 +579,37 @@
                             return test
         return None
 
-    def __getSignalVal(self, signal:Signal, data='00 01 02 03 04 05 06 07'):
+    def __getSignalVal(self, signal: Signal, data='00 01 02 03 04 05 06 07'):
         dataList = data.strip().split(' ')
         _startbit = signal.startBit
         _bitsize = signal.size
-        _little = signal.is_little_endian # (1: Intel, 0: Motorola)
-        _byteSize = math.ceil((signal.size + _startbit%8)/8)
-        _startByte = math.floor(_startbit/8)
+        _little = signal.is_little_endian  # (1: Intel, 0: Motorola)
+        _byteSize = math.ceil((signal.size + _startbit % 8) / 8)
+        _startByte = math.floor(_startbit / 8)
         phyvalue = 0
         rawvalue = ''
-        base = int('{0:0>8}'.format('1'*_bitsize+'0'*(_startbit%8)), 2)
+        base = int('{0:0>8}'.format('1' * _bitsize + '0' * (_startbit % 8)), 2)
         _byteNum = 0
-        _byteList= []
+        _byteList = []
         while _byteNum < _byteSize:
             # tmpbase = (base >> (8*_byteNum)) & 0xff
-            _byteList.append(dataList[_startByte+_byteNum])
+            _byteList.append(dataList[_startByte + _byteNum])
             _byteNum += 1
         if _little == 1:
             _byteList.reverse()
         for _byte in _byteList:
             rawvalue += _byte
-        rawvalue = ((int(rawvalue,16) & base) >> (_startbit%8))
+        rawvalue = ((int(rawvalue, 16) & base) >> (_startbit % 8))
         return {"phy": signal.raw2phys(rawvalue), "raw": rawvalue}
         # print(_startByte, _byteSize, _bitsize, int(dataList[_startByte], 16), int('{0:0>8}'.format('1'*_bitsize+'0'*(_startbit%8)), 2))
-        
+
     def analyzer(self, msgid=None, data='00 01 02 03 04 05 06 07'):
-        '''analysis given data 
-        
+        '''analysis given data
+
         Keyword Arguments:
             msgid {int} -- msg id (base 10) (default: {None})
             data {str} -- given data (default: {'00 01 02 03 04 05 06 07'})
-        
+
         Returns:
             dict -- key sorted by signal index
         '''
@@ -615,7 +629,11 @@
                 break
         return ret
 
+
 if __name__ == '__main__':
-    testDbc = DBC("data/SX7H.dbc")
-    abc=testDbc.analyzer(msgid=1056, data='40 01 C8 00 FF 00 00 00')
-    print(abc)
\ No newline at end of file
+    testDbc = DBC("DBC/DFLZM.dbc")
+    abc = testDbc.analyzer(msgid=1056, data='40 01 C8 00 FF 00 00 00')
+    print(abc)
+    print(abc[5]["name"])
+    print(abc[6]["name"])
+    print(abc[4]["name"])

--
Gitblit v1.8.0