diff --git a/src/apim.py b/src/apim.py index 823534c..8a1ff44 100644 --- a/src/apim.py +++ b/src/apim.py @@ -70,7 +70,7 @@ def open_file(self): if self.selected_file is not None: try: self.asbuilt = AsBuilt(self.selected_file) - self.encoder = ItemEncoder() + self.encoder = ItemEncoder(self.asbuilt) self.launch_picker() except ValueError as e: QMessageBox.critical(self.current_window, "Error opening file", str(e)) @@ -144,8 +144,12 @@ def launch_picker(self): self.button_save_as.clicked.connect(self.save_file_as) self.button_save.clicked.connect(self.save) self.syncversion = QComboBox() - self.syncversion.addItems(["3.0-3.2", "3.4"]) - self.syncversion.setCurrentIndex(1) + if self.asbuilt.s4: + self.syncversion.addItems(["4"]) + self.syncversion.setEnabled(False) + else: + self.syncversion.addItems(["3.0-3.2", "3.4"]) + self.syncversion.setCurrentIndex(1) self.button_group_layout.addWidget(self.button_open) self.button_group_layout.addWidget(self.button_save) @@ -317,7 +321,7 @@ def launch_qt(self): if not args.noprint: try: - print(ItemEncoder().format_all(asbuilt1, asbuilt2)) + print(ItemEncoder(asbuilt1).format_all(asbuilt1, asbuilt2)) except Exception as e: print(asbuilt1.filename, asbuilt1.blocks) raise diff --git a/src/asbuilt.py b/src/asbuilt.py index 74e83b5..cb45a1e 100644 --- a/src/asbuilt.py +++ b/src/asbuilt.py @@ -4,10 +4,14 @@ import struct class AsBuilt(object): - fieldsizes = [10, 12, 5, 7, 6, 1, 16, 10, 20] + fieldsizes_s3 = [10, 12, 5, 7, 6, 1, 16, 10, 20, 20] + fieldsizes_s4 = [20, 15, 15, 5, 15, 6, 16, 10, 25, 25] blocks = [] # 3.2 and up and later 3.0 models have 8, 9 for 3.4 from late 2019 and my20 filename = "" + s4 = False + fieldsizes = None + def __init__(self, filename): bits = "" print("Loading", filename) @@ -52,8 +56,25 @@ def __init__(self, filename): else: raise ValueError("File type not supported") self.filename = filename + # detect actual length + length = len(unhexlify(bits.encode())) + for i in range(0, len(self.fieldsizes_s3)+1): + s4 = sum(self.fieldsizes_s3[0:i]) + if s4 == length: + self.s4 = False + self.fieldsizes = self.fieldsizes_s3 + + for i in range(0, len(self.fieldsizes_s4)+1): + s4 = sum(self.fieldsizes_s4[0:i]) + if s4 == length: + self.s4 = True + self.fieldsizes = self.fieldsizes_s4 self.decode_bytes(unhexlify(bits.encode())) print("Loaded %d blocks, %d bytes" % (len(self.blocks), len(bytes(self)))) + if self.s4: + print("Device is Sync 4") + else: + print("Device is Sync 3") def decode_bytes(self, data): @@ -63,13 +84,21 @@ def decode_bytes(self, data): while len(data) > 0: try: - self.blocks.append(data[:self.fieldsizes[i]]) - data = data[self.fieldsizes[i]:] + if self.s4: + self.blocks.append(data[:self.fieldsizes_s4[i]]) + data = data[self.fieldsizes_s4[i]:] + else: + self.blocks.append(data[:self.fieldsizes_s4[i]]) + data = data[self.fieldsizes[i]:] i += 1 except: print(len(data)) + print(hexlify(data).decode()) print(i) - print(self.fieldsizes[i]) + if self.s4: + print(self.fieldsizes_s4[i]) + else: + print(self.fieldsizes[i]) def checksum(self, major, minor): return (0x07 + 0xD0 + major + minor + sum(self.blocks[major - 1][(minor-1) * 5:minor * 5])) & 0x00FF diff --git a/src/encoder.py b/src/encoder.py index 97d0a73..88a7023 100644 --- a/src/encoder.py +++ b/src/encoder.py @@ -3,7 +3,7 @@ from PyQt5.QtCore import QRegExp, Qt from functools import partial -from statics import JumpTables, Fields +from statics import JumpTables, Fields, Fields_s4 from asbuilt import AsBuilt @@ -18,6 +18,8 @@ class HmiData(object): [0, 2], [2, 2], [4, 2], [6, 1, 1], [6, 1, 2], [7, 1], [8, 1], [9, 1], [10, 1], [11, 1], [12, 2], [14, 2], [16, 2], [18, 1], [19, 1], [20, 1], [21, 2] ] + fields = None + def output_stuff(self, ab): for x in range(1, 5): print(" de%02X = [" % (x-1)) @@ -313,7 +315,10 @@ def format_de07(self, ab1, ab2=None): string = "#%s%-96s - Field Location Msk&Val = Res\n" % (" -bits-loc - " if DEBUG else "", "Name") if ab1.start_byte(8) == -1 and ab2.start_byte(8) == -1 or ab1.start_byte(8) == -1: return string - for item in Fields.de07: + fields = Fields + if ab1.s4: + fields = Fields_s4 + for item in fields.de07: bit = 7 - item['bit'] bitloc = ab1.start_bit(8) + ((item['byte']) * 8) + bit value1 = ab1.bit(bitloc, item['size'].bit_length()) @@ -345,7 +350,11 @@ def format_de08(self, ab1, ab2=None): string = "# -bits-loc - %-96s - Field Location Msk&Val = Res\n" % ("Name") if ab1.start_byte(9) == -1 and ab2.start_byte(9) == -1 or ab1.start_byte(9) == -1: return string - for item in Fields.de08: + fields = Fields + if ab1.s4: + fields = Fields_s4 + + for item in fields.de08: bit = 7 - item['bit'] bitloc = ab1.start_bit(9) + ((item['byte']) * 8) + bit value1 = ab1.bit(bitloc, item['size'].bit_length()) @@ -447,13 +456,20 @@ def byte_loc_string(self, i, bits): else: return "xxxx xxxx NNcc + NNxx xxxx xxcc" - def __init__(self): - self.items = [Fields.block(block) for block in range(1, 10)] + def __init__(self, ab): + fields = Fields + if ab.s4: + fields = Fields_s4 + self.items = [fields.block(block) for block in range(1, 10)] def QtItemList(self, block, asbuilt, bitfields, themechange): qtitems = [] prevbyte = -1 - for item in Fields.block(block): + fields = Fields + if asbuilt.s4: + fields = Fields_s4 + + for item in fields.block(block): if prevbyte != item['byte']: layout = QHBoxLayout() label = QLabel() @@ -492,7 +508,11 @@ def QtItemList(self, block, asbuilt, bitfields, themechange): option.setCurrentIndex(value) #print(item['byte']) #print(bitfields) - option.currentIndexChanged.connect(partial(combo_change, option, item, bitfields[item['byte']])) + try: + option.currentIndexChanged.connect(partial(combo_change, option, item, bitfields[item['byte']])) + except: + print("out of range", item) + elif item['type'] == 'ascii': option = QLineEdit() @@ -506,7 +526,11 @@ def QtItemList(self, block, asbuilt, bitfields, themechange): option.addItem(table[x], x) option.setMaximumWidth(400) option.setCurrentIndex(value) - option.currentIndexChanged.connect(partial(combo_change, option, item, bitfields[item['byte']])) + try: + option.currentIndexChanged.connect(partial(combo_change, option, item, bitfields[item['byte']])) + except: + print("out of range", item) + if 'theme' in item: option.currentIndexChanged.connect(partial(themechange)) layout.addWidget(label) @@ -543,84 +567,84 @@ def format(self, block, ab1, ab2): # Parking Assistance: ................................................................................ 7D0-04-02 nnXX nnnn nn 01 & FF = 01 # Front Track 7D0-05-01 XXXX nnnn nn 169B & FFFF = 169B 169B5.8 In (14.7 cm) Min: 0.0Max: 655.4 try: - for item in self.items[block-1]: - bitloc = ab1.start_bit(block) + ((item['byte']) * 8) + item['bit'] - mask = ((2**item['size'])-1) << (((7 - item['bit']) - (item['size'] - 1)) % 8) - value1 = ab1.bit(bitloc, item['size']) - value2 = ab2.bit(bitloc, item['size']) if ab2 is not None else None - byte1 = ab1.int(ab1.start_byte(block) + item['byte'], 1 + ab1.start_byte(block) + item['byte'] + (item['size'] // 8) if item['size'] % 8 != 0 else ab1.start_byte(block) + item['byte'] + (item['size'] // 8)) - byte2 = ab2.int(ab1.start_byte(block) + item['byte'], 1 + ab1.start_byte(block) + item['byte'] + (item['size'] // 8) if item['size'] % 8 != 0 else ab1.start_byte(block) + item['byte'] + (item['size'] // 8)) if ab2 is not None else None - - if mask < 256: - bitmask = "{:.>8b}".format(mask) - bitmask = bitmask.replace("0", ".") - bitmask = bitmask[:bitmask.find("1")] + ("{:0%db}" % bitmask.count("1")).format(value1) + bitmask[bitmask.find("1")+bitmask.count("1"):] - else: - bitmask = "too big " - if item['type'] == 'mul': - # multiplier type - value1 = (ab1.bit(bitloc, item['size']) * item['multiplier']) + item['offset'] - value2 = (ab2.bit(bitloc, item['size']) * item['multiplier']) + item['offset'] if ab2 is not None else None - string = string + "%s%-48s%-44s\t%s%s\t%-16s%-16s\tMin: %0.1f\tMax: %0.1f\n" %( - "%-3s - " % item['index'] if DEBUG else "", - item['name'], - ab1.mask_string(bitloc, bitloc + item['size']), - "%04X" % byte1, - " vs %04X" % byte2 if byte2 is not None else "", - "%0.1f %s%s" % (value1, item['unit'] if item['unit'] is not 'unitless' else "", " (%0.1f cm)" % (value1 * 2.54) if item['unit'] == "In" else ""), - " vs %0.1f %s%s" % (value2, item['unit'] if item['unit'] is not 'unitless' else "", " (%0.1f cm)" % (value2 * 2.54) if item['unit'] == "In" else "") if value2 is not None else "", - item['min'], - item['max'] - ) - elif item['type'] == 'mask': - # bitmask typebit = 7 - item['bit'] - string = string + "%s%-s: %s %s %s %s\n" % ( - "%-4s- %-3s - %-3s\t " % (item['index'], item['size'], bitloc) if DEBUG else "", - item['name'], - "." * (78 - len(item['name'])), - ab1.mask_string(bitloc, bitloc + item['size']), - bitmask, - "%02X" % byte1 if ab2 is None else " %02X %02X" % (byte1, byte2) - #"vs %02X & %02X = %02X" % (value2, mask, value2 & mask) if value2 is not None else "" - ) - # for now assume enable // disable if one bit or multi bit strategy - for x in range(0, item['items']): - string = string + "%s %2s %2s %s:\t%s\n" % ("\t\t" if DEBUG else "", - ">>" if ab2 is None and x == value1 else "1>" if x == value1 else "", - "2>" if ab2 is not None and x == value2 else "", - "%02X" % (x << (((7 - item['bit']) - (item['size'] - 1)) % 8)), - "" if '%d' % x not in item else item['%d' % x] + if len(self.items) >= block: + for item in self.items[block-1]: + bitloc = ab1.start_bit(block) + ((item['byte']) * 8) + item['bit'] + mask = ((2**item['size'])-1) << (((7 - item['bit']) - (item['size'] - 1)) % 8) + value1 = ab1.bit(bitloc, item['size']) + value2 = ab2.bit(bitloc, item['size']) if ab2 is not None else None + byte1 = ab1.int(ab1.start_byte(block) + item['byte'], 1 + ab1.start_byte(block) + item['byte'] + (item['size'] // 8) if item['size'] % 8 != 0 else ab1.start_byte(block) + item['byte'] + (item['size'] // 8)) + byte2 = ab2.int(ab1.start_byte(block) + item['byte'], 1 + ab1.start_byte(block) + item['byte'] + (item['size'] // 8) if item['size'] % 8 != 0 else ab1.start_byte(block) + item['byte'] + (item['size'] // 8)) if ab2 is not None else None + + if mask < 256: + bitmask = "{:.>8b}".format(mask) + bitmask = bitmask.replace("0", ".") + bitmask = bitmask[:bitmask.find("1")] + ("{:0%db}" % bitmask.count("1")).format(value1) + bitmask[bitmask.find("1")+bitmask.count("1"):] + else: + bitmask = "too big " + if item['type'] == 'mul': + # multiplier type + value1 = (ab1.bit(bitloc, item['size']) * item['multiplier']) + item['offset'] + value2 = (ab2.bit(bitloc, item['size']) * item['multiplier']) + item['offset'] if ab2 is not None else None + string = string + "%s%-48s%-44s\t%s%s\t%-16s%-16s\tMin: %0.1f\tMax: %0.1f\n" %( + "%-3s - " % item['index'] if DEBUG else "", + item['name'], + ab1.mask_string(bitloc, bitloc + item['size']), + "%04X" % byte1, + " vs %04X" % byte2 if byte2 is not None else "", + "%0.1f %s%s" % (value1, item['unit'] if item['unit'] != 'unitless' else "", " (%0.1f cm)" % (value1 * 2.54) if item['unit'] == "In" else ""), + " vs %0.1f %s%s" % (value2, item['unit'] if item['unit'] != 'unitless' else "", " (%0.1f cm)" % (value2 * 2.54) if item['unit'] == "In" else "") if value2 is not None else "", + item['min'], + item['max'] + ) + elif item['type'] == 'mask': + # bitmask typebit = 7 - item['bit'] + string = string + "%s%-s: %s %s %s %s\n" % ( + "%-4s- %-3s - %-3s\t " % (item['index'], item['size'], bitloc) if DEBUG else "", + item['name'], + "." * (78 - len(item['name'])), + ab1.mask_string(bitloc, bitloc + item['size']), + bitmask, + "%02X" % byte1 if ab2 is None else " %02X %02X" % (byte1, byte2) + #"vs %02X & %02X = %02X" % (value2, mask, value2 & mask) if value2 is not None else "" ) - elif item['type'] == 'ascii': - letterstring = " %02X: %s %s" % (value1, chr(value1), "vs %02X: %s" % (value2, chr(value2)) if value2 is not None else "") - string = string + "%s%-s: %s %s %s\n" % ("%-4s- %-3s - %-3s\t " % (item['index'], item['size'], bitloc) if DEBUG else "", - item['name'], - letterstring + "." * (78 - len(item['name']) - len(letterstring)), - ab1.mask_string(bitloc, bitloc + item['size']), - "vs %02X & %02X = %02X" % (value2, mask, value2 & mask) if value2 is not None else "" - ) - elif item['type'] == 'table': - string = string + "%s%-s: %s %s %s %s\n" % ("%-4s- %-3s - %-3s\t " % (item['index'], item['size'], bitloc) if DEBUG else "", - item['name'], - "." * (78 - len(item['name'])), - ab1.mask_string(bitloc, bitloc + item['size']), - bitmask, - "%02X" % byte1 if ab2 is None else " %02X %02X" % (byte1, byte2) - #"vs %02X & %02X = %02X" % (value2, mask, value2 & mask) if value2 is not None else "" - ) - # for now assume enable // disable if one bit or multi bit strategy - table = JumpTables.table(item['table']) - for x in range(0, len(table)): - string = string + "%s %2s %2s %s:\t%s\n" % ("\t\t" if DEBUG else "", - ">>" if ab2 is None and x == value1 else "1>" if x == value1 else "", - "2>" if ab2 is not None and x == value2 else "", - "%02X" % x, - "" if len(table) < x not in item else table[x] + # for now assume enable // disable if one bit or multi bit strategy + for x in range(0, item['items']): + string = string + "%s %2s %2s %s:\t%s\n" % ("\t\t" if DEBUG else "", + ">>" if ab2 is None and x == value1 else "1>" if x == value1 else "", + "2>" if ab2 is not None and x == value2 else "", + "%02X" % (x << (((7 - item['bit']) - (item['size'] - 1)) % 8)), + "" if '%d' % x not in item else item['%d' % x] + ) + elif item['type'] == 'ascii': + letterstring = " %02X: %s %s" % (value1, chr(value1), "vs %02X: %s" % (value2, chr(value2)) if value2 is not None else "") + string = string + "%s%-s: %s %s %s\n" % ("%-4s- %-3s - %-3s\t " % (item['index'], item['size'], bitloc) if DEBUG else "", + item['name'], + letterstring + "." * (78 - len(item['name']) - len(letterstring)), + ab1.mask_string(bitloc, bitloc + item['size']), + "vs %02X & %02X = %02X" % (value2, mask, value2 & mask) if value2 is not None else "" ) - # table type - pass + elif item['type'] == 'table': + string = string + "%s%-s: %s %s %s %s\n" % ("%-4s- %-3s - %-3s\t " % (item['index'], item['size'], bitloc) if DEBUG else "", + item['name'], + "." * (78 - len(item['name'])), + ab1.mask_string(bitloc, bitloc + item['size']), + bitmask, + "%02X" % byte1 if ab2 is None else " %02X %02X" % (byte1, byte2) + #"vs %02X & %02X = %02X" % (value2, mask, value2 & mask) if value2 is not None else "" + ) + # for now assume enable // disable if one bit or multi bit strategy + table = JumpTables.table(item['table']) + for x in range(0, len(table)): + string = string + "%s %2s %2s %s:\t%s\n" % ("\t\t" if DEBUG else "", + ">>" if ab2 is None and x == value1 else "1>" if x == value1 else "", + "2>" if ab2 is not None and x == value2 else "", + "%02X" % x, + "" if len(table) < x not in item else table[x] + ) + # table type + pass except Exception as e: - print(item) print(block) raise e return string + "\n" @@ -675,6 +699,14 @@ def print_duplicates(): block = Fields.block(i) for item in block: if item['index'] in indexes: - print("Duplicate: %d", item['index']) + print("Duplicate: %d" % item['index']) + else: + indexes.append(item['index']) + indexes = [] + for i in range(1, 11): + block = Fields_s4.block(i) + for item in block: + if item['index'] in indexes: + print("Duplicate: %d" % item['index']) else: indexes.append(item['index']) diff --git a/src/statics.py b/src/statics.py index ee54cdc..b018b58 100644 --- a/src/statics.py +++ b/src/statics.py @@ -93,6 +93,37 @@ class JumpTables(object): "Lincoln U540 (Lincoln D544/Lincoln Classic but sets MY20 theme)", ] + _SSS4 = [ + "Default", + "Stock determined by brand bit", + "F150", + "Raptor", + "Black label", + "Presidential", + "Non-shelby Mustang", + "Shelby Mustang", + "Mustang Shelby R1", + "Mustang EVO", + "Base Ford (Europe)", + "ST", + "RS", + "Ford GT", + "Continental", + "Navigator", + "Aviator", + "Escape", + "Explorer", + "Expedition", + "Bronco", + "Maverick (CX430)", + "Vignale", + "Active" + "ST Line", + "CS727", + "Corsair (CX483)", + "Nautilus (U540)" + ] + _VS = [ "Undefined", "Sedan", @@ -100,7 +131,13 @@ class JumpTables(object): "Pickup Truck", "SUV/CUV", "VAN", - "Hatchback" + "Hatchback", + "Wagon", + "Small Commuter Van PDC", + "EcoSport PDC", + "Fiesta PDC", + "Bronco", + "Muscle Car", ] _DT = [ @@ -176,8 +213,8 @@ class JumpTables(object): "Rear/Front PDC with APA", "APA Lite", "APA Lite Plus (SAPP/POA - 10 Channel)", - "0A Unknkown / Reserved", - "0B Unknkown / Reserved", + "APACSI", + "FAPA", "0C Unknkown / Reserved", "0D Unknkown / Reserved", "0E Unknkown / Reserved", @@ -188,14 +225,32 @@ class JumpTables(object): ] _V = [ # case vehicle type - "Non HEV, BEV, PHEV", + "Non programmable", #0 "C344", - "C346", + "C346/C519", #2 "CD391", - "CD533", - "Unknown", - "Unknown", - "Unknown" + "CD533", #4 + "U611", + "U625", #6 + "CX482", + "CX483", #8 + "CX727", + "P758", #a + "P702", + "CD539", #c + "U725", + "U540", + "CX482N", #f + "P558", + "P702 ICA (Raptor)", + "U553", + "U554", + "CD542", + "V363", + "P702 BEV", + "U704", + "P703", + "V713", ] _VDV = [ # case visual design variant @@ -210,6 +265,19 @@ class JumpTables(object): "Ford 10\" MY20", ] + _VDVS4 = [ + "8\" Landscape", + "10\" Portrait", + "10\" Landscape", + "12\" Landscape", + "12\" Portrait (Dashcard)", + "13.2\" Landscape Lincoln (Dashcard)", + "13.2\" Landscape Ford (Dashcard)", + "15\" Portrait (Dashcard)", + "10\" Portrait (Dashcard)", + "13.2\" Landscape (Qt based)", + ] + _KC = [ # case KEY combination "Volume Down + F1", "Volume Down + Home", @@ -220,6 +288,64 @@ class JumpTables(object): BAPI = [ # Bluetooth audi profile index "Profile %d" ] + + _BAPI = [ + "Profile 1", + "U502 - Ford Explorer (Ext Amp)", + "MKZ (Ext Amp)", + "U387 - Edge", + "C344 - CMAX (Int Amp)", + "D258 - Taurus (Ext Amp)", + "C520 - Escape (Ext Amp)", + "B299 - Fiesta (Ext Amp)", + "U222 - Expedition (Ext Amp)", + "S550 - Mustang (Ext Amp)", + "V363N - Transit (Int Amp)", + "C346N - Focus / Generic Compact", + "Generic Small Xover (Int Amp)", + "Generic Small Xover (Ext Amp)", + "Generic Large Sedan", + "Generic Large SUV", + "U228 - Lincoln Navigator", + "D471 - Flex (Ext Amp)", + "D472 - MKT (Ext Amp)", + "C346N - Focus ST (Int Amp)", + "P552 - F-150 with Sony", + "EU CMAX C344E", + "EU Edge CD539X", + "EU Explorer U502", + "EU Fiesta B299", + "EU Focus C346E", + "EU Galaxy CD390E Smax CD539E", + "EU Kuga C520E", + "EU Mondeo CD391E", + "EU Mustang S550", + "EU Transit 363E", + "EU Transit Connect V408", + "MKX U540", + "D568C", + "U375A LHD", + "U375A RHD", + "P375A LHD", + "P375A RHD", + "Ford GT", + "V362 OHC mic", + "V362 HL mic", + "B460", + "B562 HL", + "B562 OHC", + "P375 Ranger-DoubleCab", + "U375 Everest MoonRoof", + "U375 Everest Standard Roof", + "P473 - Superduty", + "P375 Ranger DBL (Branded)", + "P375 Ranger DBL (Unbranded)", + "MY19 D568 Branded (New Mic Location)", + "MY19 D568 Unbranded (New Mic Location)", + "V363N - Transit HL mic", + "CX727", + "U725", + ] _AFL = [ # Electronic horizon" "Electronic Horizon Off", "Electronic Horizon for Informational Use Only", @@ -3778,6 +3904,3223 @@ def block(cls, block): }, ] + +class Fields_s4(object): + + @classmethod + def combine(cls, start, stop): + data = [] + for i in range(start, stop): + if not hasattr(cls, 'de%02X' % (i)): + break; + data = data + getattr(cls, 'de%02X' % (i)) + return data + + @classmethod + def block(cls, block): + if not hasattr(cls, "de%02X" % (block-1)): + print(block, getattr(cls, "de%02X" % (block-1))) + return None + return getattr(cls, "de%02X" % (block-1)) + + de00 = [ + { + 'name': 'Smart DSP', + 'index': 1, + 'byte': 0, + 'bit': 0, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Do not log missing DSP Messages', + '1': 'Enable, Log missing DSP Messages (When configured for Smart DSP and Lincoln then enable THX Deep Note)', + }, + { + 'name': 'AAM (Module is related to Smart DSP)', + 'index': 2, + 'byte': 0, + 'bit': 1, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Do not log missing AAM messages', + '1': 'Enable, Log Missing AAM messages (Send speaker walkaround request to ACM)', + }, + { + 'name': 'SDARS', + 'index': 3, + 'byte': 0, + 'bit': 2, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Do not log missing SDARS (ACM) message', + '1': 'Enable, Log Missing SDARS (ACM) message', + }, + { + 'name': 'RSEM', + 'index': 4, + 'byte': 0, + 'bit': 3, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Do not log missing RSEM messages', + '1': 'Enable, Log Missing RSEM messages', + }, + { + 'name': 'FSM Fader in sound menu', + 'index': 5, + 'byte': 0, + 'bit': 4, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + }, + { + 'name': 'Tuner type', + 'index': 6, + 'byte': 0, + 'bit': 5, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'TT Single tuner', + '1': 'TT Dual tuner', + }, + { + 'name': 'TMC', + 'index': 7, + 'byte': 0, + 'bit': 6, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'DAB', + 'index': 7, + 'byte': 0, + 'bit': 7, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'HDR', + 'index': 8, + 'byte': 1, + 'bit': 0, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'RTM Market', + 'index': 9, + 'byte': 1, + 'bit': 1, + 'size': 1, + 'items': 4 , + 'type': 'mask', + '0': 'Non RDS Market', + '1': 'RDS Market', + }, + { + 'name': 'REFP', + 'index': 10, + 'byte': 1, + 'bit': 2, + 'size': 1, + 'items': 4 , + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'SSAOM', + 'index': 11, + 'byte': 1, + 'bit': 3, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Available', + '1': 'Not available', + }, + { + 'name': 'BOTTHMI', + 'index': 12, + 'byte': 1, + 'bit': 4, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'REVEL Sound System', + 'index': 13, + 'byte': 1, + 'bit': 5, + 'size': 2, + 'items': 4 , + 'type': 'mask', + '0': 'Not Present', + '1': 'Present', + '2': 'Unknown', + '3': 'Unknown', + }, + { + 'name': 'Presets type', + 'index': 13, + 'byte': 1, + 'bit': 7, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Normal Presets (A Enabled)', + '1': 'Mixed Mode Presets (A Disabled)' + }, + { + 'name': 'Brazilian frequency support', + 'index': 14, + 'byte': 2, + 'bit': 1, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Supported', + '1': 'Not supported', + }, + { + 'name': 'Unknown', + 'index': 15, + 'byte': 2, + 'bit': 2, + 'size': 3, + 'items': 2, + 'type': 'mask', + '0': 'Unknown', + }, + { + 'name': 'X40 Radio Present', + 'index': 16, + 'byte': 2, + 'bit': 4, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Pre-X40', + '1': 'X40', + }, + { + 'name': 'Sound Immersion', + 'index': 17, + 'byte': 2, + 'bit': 6, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'USB Self Test Detection', + 'index': 18, + 'byte': 2, + 'bit': 7, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + }, + { + 'name': 'Extended Play', + 'index': 19, + 'byte': 3, + 'bit': 0, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + }, + { + 'name': 'Extended playtime', + 'index': 20, + 'byte': 3, + 'bit': 1, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': '20 minutes', + '1': '30 minutes (FNA)', + '2': '40 minutes', + '3': '60 minutes (FoE)', + }, + { + 'name': 'FM Tuner', + 'index': 21, + 'byte': 3, + 'bit': 3, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'FM Tuner available', + '1': 'FM Tuner not available', + }, + { + 'name': 'AM Tuner', + 'index': 22, + 'byte': 3, + 'bit': 4, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'AM Tuner available', + '1': 'AM Tuner not available', + }, + { + 'name': 'Number of mixed mode presets per page', + 'index': 23, + 'byte': 3, + 'bit': 5, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': '6 per page', + '1': '5 per page', + '2': '10 per page', + '3': 'Reserved', + }, + { + 'name': 'VR for Radio Tuner', + 'index': 24, + 'byte': 3, + 'bit': 7, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'Rear camera', + 'index': 25, + 'byte': 4, + 'bit': 0, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'Front camera', + 'index': 26, + 'byte': 4, + 'bit': 1, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'Rear camera split view', + 'index': 27, + 'byte': 4, + 'bit': 2, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': '360 Camera view', + 'index': 28, + 'byte': 4, + 'bit': 3, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'DAFVC Split view', + 'index': 29, + 'byte': 4, + 'bit': 4, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'Multi Camera Strategy', + 'index': 30, + 'byte': 4, + 'bit': 5, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Hard button toggle', + '1': 'Soft button toggle', + }, + { + 'name': 'Trailer Reverse Guidance', + 'index': 31, + 'byte': 4, + 'bit': 6, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'CHMSL Camera', + 'index': 32, + 'byte': 4, + 'bit': 7, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Aux camera', + 'index': 33, + 'byte': 5, + 'bit': 0, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'RVC Split Camera', + 'index': 34, + 'byte': 5, + 'bit': 1, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': '360 Offset views', + 'index': 35, + 'byte': 5, + 'bit': 2, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'Steering Angle', + 'index': 36, + 'byte': 5, + 'bit': 3, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Pinion', + '1': 'Wheel', + }, + { + 'name': 'Driver Restriction Images', + 'index': 37, + 'byte': 5, + 'bit': 4, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Allowed', + '1': 'Restricted', + }, + { + 'name': 'Park Hold', + 'index': 38, + 'byte': 5, + 'bit': 5, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled (Hitch improvement feature)', + '2': 'Reserved', + '3': 'Reserved', + }, + { + 'name': 'Type of Rear View Camera', + 'index': 39, + 'byte': 5, + 'bit': 7, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Analogue', + '1': 'Digital', + }, + { + 'name': 'Digital Camera Vehicle Settings', + 'index': 40, + 'byte': 6, + 'bit': 0, + 'size': 6, + 'items': 64, + 'type': 'mask', + '0': 'Vehicle 1', + '1': 'Vehicle 2', + '2': 'Vehicle 3', + '3': 'Vehicle 4', + '4': 'Vehicle 5', + '5': 'Vehicle 6', + '6': 'Vehicle 7', + '7': 'Vehicle 8', + '8': 'Vehicle 9', + '9': 'Vehicle 10', + '10': 'Vehicle 11', + '11': 'Vehicle 12', + '12': 'Vehicle 13', + '13': 'Vehicle 14', + '14': 'Vehicle 15', + '15': 'Vehicle 16', + '16': 'Vehicle 17', + '17': 'Vehicle 18', + '18': 'Vehicle 19', + '19': 'Vehicle 20', + '20': 'Vehicle 21', + '21': 'Vehicle 22', + '22': 'Vehicle 23', + '23': 'Vehicle 24', + '24': 'Vehicle 25', + '25': 'Vehicle 26', + '26': 'Vehicle 27', + '27': 'Vehicle 28', + '28': 'Vehicle 29', + '29': 'Vehicle 30', + '30': 'Vehicle 31', + '31': 'Vehicle 32', + '32': 'Vehicle 33', + '33': 'Vehicle 34', + '34': 'Vehicle 35', + '35': 'Vehicle 36', + '36': 'Vehicle 37', + '37': 'Vehicle 38', + '38': 'Vehicle 39', + '39': 'Vehicle 40', + '40': 'Vehicle 41', + '41': 'Vehicle 42', + '42': 'Vehicle 43', + '43': 'Vehicle 44', + '44': 'Vehicle 45', + '45': 'Vehicle 46', + '46': 'Vehicle 47', + '47': 'Vehicle 48', + '48': 'Vehicle 49', + '49': 'Vehicle 50', + '50': 'Vehicle 51', + '51': 'Vehicle 52', + '52': 'Vehicle 53', + '53': 'Vehicle 54', + '54': 'Vehicle 55', + '55': 'Vehicle 56', + '56': 'Vehicle 57', + '57': 'Vehicle 58', + '58': 'Vehicle 59', + '59': 'Vehicle 60', + '60': 'Vehicle 61', + '61': 'Vehicle 62', + '62': 'Vehicle 63', + '63': 'Vehicle 64', + }, + { + 'name': 'Front rock crawl', + 'index': 41, + 'byte': 6, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not Present', + '1': 'Present', + }, + { + 'name': 'Rear Rock Crawl', + 'index': 42, + 'byte': 6, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not Present', + '1': 'Present', + }, + { + 'name': 'CAN SWC (responds to can bus button signals)', + 'index': 43, + 'byte': 7, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not avaliable', + '1': 'Available', + }, + { + 'name': 'Ignition Type', + 'index': 44, + 'byte': 7, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Key start', + '1': 'Push button start', + }, + { + 'name': 'WOW Seat', + 'index': 45, + 'byte': 7, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not present', + '1': 'Present', + }, + { + 'name': 'Start/Stop Vehicle', + 'index': 46, + 'byte': 7, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Non Start/Stop', + '1': 'Start/Stop', + }, + { + 'name': 'Transmission type', + 'index': 47, + 'byte': 7, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Automatic', + '1': 'Manual', + }, + { + 'name': 'Ambient Lighting', + 'index': 48, + 'byte': 7, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'Door keypad code', + 'index': 49, + 'byte': 7, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'Legacy multi-countoured Seats', + 'index': 50, + 'byte': 7, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'HW SWC', + 'index': 51, + 'byte': 8, + 'bit': 0, + 'size': 2, + 'items': 4 , + 'type': 'mask', + '0': 'Not Available', + '1': 'SWAC with volume, PTT... (Variant C)', + '2': 'SWAC with Mode, Seek, etc... (Variant A)', + '3': 'Reserved', + }, + { + 'name': 'Number of Bladders', + 'index': 52, + 'byte': 8, + 'bit': 2, + 'size': 2, + 'items': 4 , + 'type': 'mask', + '0': 'Other', + '1': '3 Bladders', + '2': '7 Bladders', + '3': '11 Bladders', + }, + { + 'name': 'Park brake type', + 'index': 53, + 'byte': 8, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Mechenical', + '1': 'Electronic', + }, + { + 'name': 'Trailer backup assistant', + 'index': 54, + 'byte': 8, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'Enhanced Memory', + 'index': 55, + 'byte': 8, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Cross Traffic Alert', + 'index': 56, + 'byte': 8, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Number of Personalizations', + 'index': 57, + 'byte': 9, + 'bit': 0, + 'size': 2, + 'items': 4 , + 'type': 'mask', + '0': 'Disabled', + '1': '2', + '2': '3', + '3': '4', + }, + { + 'name': 'WACM', + 'index': 58, + 'byte': 9, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not Present', + '1': 'Present', + }, + { + 'name': 'Ambint Lighting Type', + 'index': 59, + 'byte': 9, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Pantone', + '1': 'Single Color', + }, + { + 'name': 'Reverse Gear', + 'index': 60, + 'byte': 9, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Legacy', + '1': 'New', + }, + { + 'name': 'Phone as Key', + 'index': 61, + 'byte': 9, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not present', + '1': 'Present', + }, + { + 'name': 'Trailer Aid Signal Source', + 'index': 62, + 'byte': 9, + 'bit': 6, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'Not available', + '1': 'Available with PSCM', + '2': 'Available with IPMB', + '3': 'Reserved', + }, + { + 'name': 'Boundary Alert', + 'index': 63, + 'byte': 10, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Reverse Brake Assist', + 'index': 64, + 'byte': 10, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Enhanced MSC', + 'index': 65, + 'byte': 10, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Ambient Lighting System Strategy', + 'index': 66, + 'byte': 10, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Variant 1', + '1': 'Variant 2', + }, + { + 'name': 'Power Lumbar', + 'index': 67, + 'byte': 10, + 'bit': 4, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'Disabled', + '1': '2 Way', + '2': '4 Way', + '3': 'Reserved', + }, + { + 'name': 'Parking Hot Key', + 'index': 64, + 'byte': 10, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Camera Hot Key', + 'index': 65, + 'byte': 10, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Driver Assist Hot Key', + 'index': 66, + 'byte': 11, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Auto Hold', + 'index': 67, + 'byte': 11, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Video On Demand', + 'index': 68, + 'byte': 11, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Driver Only MCS ', + 'index': 69, + 'byte': 11, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': '360 Lighting', + 'index': 66, + 'byte': 11, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': '360 Lighting: Number of Zones', + 'index': 67, + 'byte': 11, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': '2 Zones', + '1': '4 Zones', + }, + { + 'name': 'Architecture Version', + 'index': 68, + 'byte': 11, + 'bit': 6, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'Reserved', + '1': 'FNV2', + '2': 'Reserved', + '3': 'Reserved', + }, + { + 'name': 'Backup Start Passcode', + 'index': 69, + 'byte': 12, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Redcap', + 'index': 69, + 'byte': 12, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Trailer Backup Assist 2 Feature', + 'index': 69, + 'byte': 12, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'Dark Car Mode', + 'index': 69, + 'byte': 12, + 'bit': 3, + 'size': 2, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Legacy', + '2': 'Version 2.0', + '3': 'Reserved', + }, + { + 'name': 'Power to the Box', + 'index': 69, + 'byte': 12, + 'bit': 5, + 'size': 2, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled with 1 dial', + '2': 'Enabled with 2 dials', + '3': 'Reserved', + }, + { + 'name': 'Trailer Reverse Guidance 2 Feature', + 'index': 69, + 'byte': 12, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not Available', + '1': 'Available', + }, + { + 'name': 'Trailer Settings Feature', + 'index': 69, + 'byte': 13, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Trailer Setup Configuration', + 'index': 69, + 'byte': 13, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Trailer Vehicle Style', + 'index': 69, + 'byte': 13, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'SUV', + '1': 'Truck', + }, + { + 'name': 'Autohitch ', + 'index': 69, + 'byte': 13, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Autofeature', + 'index': 69, + 'byte': 13, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Trailer Lighting', + 'index': 69, + 'byte': 13, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'TBA Fifth Wheel Support', + 'index': 69, + 'byte': 13, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Integrated Trailer Module', + 'index': 69, + 'byte': 13, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Trailer Measurement ', + 'index': 69, + 'byte': 14, + 'bit': 0, + 'size': 2, + 'items': 2, + 'type': 'mask', + '0': 'No measurement', + '1': 'Measurements', + '2': 'Sticker', + '3': 'Reserved', + }, + { + 'name': 'IOD - Pitch/Roll', + 'index': 69, + 'byte': 14, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - Eco Behavior', + 'index': 69, + 'byte': 14, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - Trip 1/2', + 'index': 69, + 'byte': 14, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - Fuel Economy', + 'index': 69, + 'byte': 14, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - Zone Lighting', + 'index': 69, + 'byte': 14, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - Bed Camera', + 'index': 69, + 'byte': 14, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': '360 Lighting Vehicle HMI', + 'index': 69, + 'byte': 15, + 'bit': 3, + 'size': 3, + 'items': 8, + 'type': 'mask', + '0': 'Vehicle 1 (P702) ', + '1': 'Vehicle 2 (U725)', + '2': 'Vehicle 3 (P703)', + '3': 'Vehicle 4 (U704)', + '4': 'Vehicle 5 (P702 VEV) ', + '5': 'Vehicle 6 (U553)', + '6': 'Vehicle 7 (P708) ', + '7': 'Unknown', + }, + { + 'name': 'IOD - Navigation', + 'index': 69, + 'byte': 15, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - On Board Generator', + 'index': 69, + 'byte': 15, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - Phone', + 'index': 69, + 'byte': 16, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - Audio', + 'index': 69, + 'byte': 16, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'IOD - TPMS', + 'index': 69, + 'byte': 16, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Eco-Idle', + 'index': 69, + 'byte': 16, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + + { + 'name': 'Advanced HUD', + 'index': 69, + 'byte': 16, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': '4 Pin/7 Pin Trailer Connector', + 'index': 69, + 'byte': 16, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'No connector/4 Pin', + '1': '7 Pin', + }, + { + 'name': 'IPD-Off-Road #2', + 'index': 69, + 'byte': 16, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Seats Hot Key', + 'index': 69, + 'byte': 16, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'RCOD View', + 'index': 69, + 'byte': 17, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Hitch View', + 'index': 69, + 'byte': 17, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'CHMSL View at Speed', + 'index': 69, + 'byte': 17, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Aux View at Speed', + 'index': 69, + 'byte': 17, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'RCOD View at Speed', + 'index': 69, + 'byte': 17, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Hitch View at Speed', + 'index': 69, + 'byte': 17, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': '1 Pedal Drive', + 'index': 69, + 'byte': 17, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Off road Views at Speed', + 'index': 69, + 'byte': 17, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Selectable Drive Modes', + 'index': 69, + 'byte': 18, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Camera Soft Button', + 'index': 69, + 'byte': 18, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'DSM', + 'index': 69, + 'byte': 18, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Rocket Setup', + 'index': 69, + 'byte': 18, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + + { + 'name': 'Number of Bladders Continued', + 'index': 69, + 'byte': 18, + 'bit': 4, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': '21 Bladders', + '1': '17 Bladders', + '2': 'Reserved', + '3': 'Reserved', + }, + { + 'name': '360 Camera View Format', + 'index': 69, + 'byte': 18, + 'bit': 6, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'Horizontal', + '1': 'Vertical (360 top)', + '2': 'Reserved', + '3': 'Reserved', + }, + { + 'name': 'Seats Hot Key - Number of Buttons', + 'index': 69, + 'byte': 19, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Single', + '1': 'Double', + }, + { + 'name': 'Trailer Light Check', + 'index': 69, + 'byte': 19, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + + + ] + + de01 = [ + { + 'name': 'TRG Picture in Picture', + 'byte': 0, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Vehicle Driver Location', + 'byte': 0, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Left hand drive', + '1': 'Right hand drive', + }, + { + 'name': 'Brand', + 'byte': 0, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Ford', + '1': 'Lincoln', + }, + { + 'name': 'List Browser', + 'byte': 0, + 'bit': 3, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'Navigation and media', + '1': 'Navigation only', + '2': 'None', + '3': 'Reserved', + }, + { + 'name': 'Calm Screen', + 'byte': 0, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': '4.2 HMI Menu Controller', + 'byte': 0, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Rotary Tune Knob with OK Button', + '1': '5-Way Controller', + }, + { + 'name': 'Gracenote ', + 'byte': 0, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + }, + { + 'name': 'Alexa HMI', + 'byte': 1, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': ' OTA Automatic Updates HMI', + 'byte': 1, + 'bit': 1, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + '2': 'Reserved', + '3': 'Reserved', + + }, + { + 'name': 'Features Domain Button', + 'byte': 1, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not present', + '1': 'Present', + }, + { + 'name': 'Favorite Domain', + 'byte': 1, + 'bit': 4, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'No Favorite Domain', + '1': '1 Favorite Domain Button', + '2': '2 Favorite Domain Buttons', + '3': 'Reserved', + }, + { + 'name': 'Display Off', + 'byte': 1, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Off-Road Turn Assist', + 'byte': 1, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Climate Front Zones', + 'byte': 2, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Dual zone', + '1': 'Single zone', + }, + { + 'name': 'Smart Auto', + 'byte': 2, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Rear Climate', + 'byte': 2, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'Heated Steering Wheel', + 'byte': 2, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'Heated Seats HMI', + 'byte': 2, + 'bit': 4, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': 'None (Hard buttons or No Heated or Cooled Seats)', + '1': 'Cooled Only', + '2': 'Heated and Cooled', + '3': 'Heated Only (3-Level)', + }, + { + 'name': 'Mode Man', + 'byte': 2, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Climate Control Type', + 'byte': 2, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Automatic', + '1': 'Manual', + }, + { + 'name': 'Recirc Icon', + 'byte': 3, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Heated Windshield HMI', + 'byte': 3, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not present', + '1': 'Present', + }, + { + 'name': 'Rear Climate Type', + 'byte': 3, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Rear Manual w/o Air Flow Mode', + '1': 'Rear Manual w/ Air Flow Mode', + '2': 'Automatic', + '3': 'Fan Only', + }, + { + 'name': 'Outside Air Temperature HMI ', + 'byte': 3, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Off', + '1': 'On', + }, + { + 'name': 'Rear Defrost', + 'byte': 3, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Off', + '1': 'On', + }, + { + 'name': 'Climate Domain', + 'byte': 3, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Off', + '1': 'On', + }, + { + 'name': 'Fan Repeater', + 'byte': 3, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Off', + '1': 'On', + }, + { + 'name': 'Temperature Repeater', + 'byte': 4, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Off', + '1': 'On', + }, + { + 'name': 'Eheat ', + 'byte': 4, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Quad Zone', + 'byte': 4, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Auto Air Refresh', + 'byte': 4, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'PM Sensor for Auto Air Refresh', + 'byte': 4, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': '2.5', + '1': '10', + }, + { + 'name': 'Power ', + 'byte': 4, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Dual ', + 'byte': 4, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Max Defrost', + 'byte': 4, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Max A/C', + 'byte': 5, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Status Bar Temperature', + 'byte': 5, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'On', + '1': 'Off', + }, + { + 'name': 'Driver Focused Climate', + 'byte': 5, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Climate Auto Seats', + 'byte': 5, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Climate Auto Heated Steering Wheel', + 'byte': 5, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Mirror Defrost', + 'byte': 5, + 'bit': 6, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Off', + '1': 'On', + }, + { + 'name': 'Hybrid Vehicle', + 'byte': 6, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not a HEV', + '1': 'HEV', + }, + { + 'name': 'PHEV', + 'byte': 6, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not available', + '1': 'Available', + }, + { + 'name': 'Charge Port Lock', + 'byte': 6, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not present', + '1': 'Present', + }, + { + 'name': 'Powerflow Type', + 'byte': 6, + 'bit': 4, + 'size': 2, + 'items': 2, + 'type': 'mask', + '0': 'None', + '1': 'MHT', + '2': 'PS', + '3': 'PS w/ ERAD 4WD', + }, + { + 'name': 'Charge Port Type', + 'byte': 7, + 'bit': 2, + 'size': 3, + 'items': 8, + 'type': 'mask', + '0': 'No charge port', + '1': 'Type 1', + '2': 'Type 1 Combo', + '3': 'Type 2', + '4': 'Type 2 Combo', + '5': 'China AC', + '6': 'Chine DC', + '7': 'Reserved', + }, + { + 'name': 'Battery Pack Size', + 'byte': 7, + 'bit': 5, + 'size': 3, + 'items': 8, + 'type': 'mask', + '0': '3p', + '1': '4p', + '2': 'Reserved', + '3': 'Reserved', + '4': 'Reserved', + '5': 'Reserved', + '6': 'Reserved', + '7': 'Reserved', + }, + { + 'name': 'TCU ', + 'byte': 8, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not present', + '1': 'Present', + }, + { + 'name': 'Hotspot Capable Modem', + 'byte': 8, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not present', + '1': 'Present', + }, + { + 'name': 'HS4 Network', + 'byte': 8, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Customer Connectivity Setting', + 'byte': 8, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'TCU Reset', + 'byte': 8, + 'bit': 4, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'GPS from TCU', + 'byte': 8, + 'bit': 5, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Not present', + '1': 'Present', + }, + { + 'name': 'Other Brand ', + 'byte': 8, + 'bit': 6, + 'size': 2, + 'items': 2, + 'type': 'mask', + '0': 'Standard Ford/Lincoln', + '1': 'Other brand 1', + '2': 'Other brand 2', + '3': 'Other brand 3', + }, + { + 'name': 'Android Auto Projection', + 'byte': 9, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + }, + { + 'name': 'Emergency Assistance', + 'byte': 9, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + }, + { + 'name': 'AA OE Channel Feature', + 'byte': 9, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + }, + { + 'name': 'Mobile Navigation', + 'byte': 9, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Enabled', + '1': 'Disabled', + }, + { + 'name': 'Number of Telephony Buttons', + 'byte': 9, + 'bit': 7, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': '1', + '1': '2', + }, + { + 'name': 'ICP Type', + 'byte': 10, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'EFP', + '1': 'ICP', + }, + { + 'name': 'ICP Branding', + 'byte': 10, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Non branded', + '1': 'Branded', + }, + { + 'name': 'ICP Network', + 'byte': 10, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'CAN', + '1': 'LIN', + }, + { + 'name': 'ICP Present', + 'byte': 10, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Present', + '1': 'Not preent (Touchscreen HMI On Button)', + }, + { + 'name': 'Rear Seat Occupant', + 'byte': 10, + 'bit': 0, + 'size': 4, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Illumination Change Step/Gradual', + 'byte': 11, + 'bit': 1, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Step change', + '1': 'Gradual change', + }, + { + 'name': 'Illumination', + 'byte': 11, + 'bit': 2, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'On', + '1': 'Off', + }, + { + 'name': 'Keypad', + 'byte': 11, + 'bit': 3, + 'size': 2, + 'items': 2, + 'type': 'mask', + '0': '5', + '1': '7', + '2': 'Reserved', + '3': 'Reserved', + }, + { + 'name': 'Keypad', + 'byte': 10, + 'bit': 0, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + ] + + de02 = [ + { + 'name': 'First Letter of Country Code-ASCII', + 'index': 70, + 'byte': 0, + 'bit': 0, + 'size': 8, + 'type': 'ascii', + }, + { + 'name': 'Second Letter of Country Code-ASCII', + 'index': 71, + 'byte': 1, + 'bit': 0, + 'size': 8, + 'type': 'ascii', + }, + { + 'name': 'Splash Screen', + 'index': 1, + 'byte': 2, + 'bit': 0, + 'size': 8, + 'type': 'table', + 'table': '__SSS4' + }, + { + 'name': 'Vehicle Style', + 'index': 1, + 'byte': 3, + 'bit': 0, + 'size': 8, + 'type': 'table', + 'table': '__VS' + }, + { + 'name': 'Vehicle Design Variants', + 'index': 1, + 'byte': 4, + 'bit': 0, + 'size': 8, + 'type': 'table', + 'table': '__VDVS4' + }, + { + 'name': 'Vehicle', + 'index': 73, + 'byte': 5, + 'bit': 0, + 'size': 8, + 'type': 'table', + 'table': '__V', + }, + { + 'name': 'Bluetooth Audio Profile Index ', + 'index': 73, + 'byte': 6, + 'bit': 0, + 'size': 16, + 'type': 'table', + 'table': '__BAPI', + }, + { + 'name': 'Bluetooth Vehicle Nameplate ID', + 'index': 73, + 'byte': 8, + 'bit': 0, + 'size': 8, + 'type': 'table', + 'table': 'BVNI', + }, + { + 'name': 'LIN 11-X', + 'index': 225, + 'byte': 9, + 'bit': 0, + 'type': 'mul', + 'size': 4, + 'offset': 0, + 'multiplier': 1, + 'unit': 'unitless', + 'min': 0, + 'max': 15, + + }, + { 'name': 'LIN 12-Y', + 'index': 228, + 'byte': 9, + 'bit': 4, + 'type': 'mul', + 'size': 4, + 'offset': 0, + 'multiplier': 1, + 'unit': 'unitless', + 'min': 0, + 'max': 15, + + }, + { 'name': 'LIN 13-Z', + 'index': 227, + 'byte': 10, + 'bit': 0, + 'type': 'mul', + 'size': 4, + 'offset': 0, + 'multiplier': 1, + 'unit': 'unitless', + 'min': 0, + 'max': 15, + + }, + { + 'name': 'SDM Max Response Time', + 'byte': 10, + 'bit': 4, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': "None", + '1': "200 ms", + '2': '500 ms', + '3': 'Reserved', + }, + { + 'name': 'SDM Max Feedback Errors', + 'byte': 10, + 'bit': 6, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': "None", + '1': "3", + '2': 'Reserved', + '3': 'Reserved', + }, + { + 'name': 'SDM Program HMI', + 'byte': 11, + 'bit': 0, + 'size': 2, + 'items': 4, + 'type': 'mask', + '0': "Ford HMI Names", + '1': "Lincoln HMI Names", + '2': 'BEV HMI Names', + '3': 'Program HMI Names', + }, + { + 'name': 'Massage Pattern', + 'byte': 12, + 'bit': 0, + 'size': 8, + 'items': 15, + 'type': 'mask', + '0': "Pattern Set 1", + '1': "Pattern Set 2", + '2': 'Pattern Set 3', + '3': 'Pattern Set 4', + '4': "Pattern Set 5", + '5': "Pattern Set 6", + '6': 'Pattern Set 7', + '7': 'Pattern Set 8', + '8': "Pattern Set 9", + '9': "Pattern Set 10", + '10': 'Pattern Set 11', + '11': 'Pattern Set 12', + '12': "Pattern Set 13", + '13': "Pattern Set 14", + '14': 'Pattern Set 15', + } + ] + + + de03 = [ + { + 'name': 'BT Pairing Timeout in seconds', + 'index': 99121, + 'byte': 0, + 'bit': 0, + 'size': 8, + 'type': 'mul', + 'offset': 0, + 'multiplier': 1, + 'unit': 'seconds', + 'min': 0, + 'max': 255, + }, + ] + + de04 = [ + { + 'name': 'Speed limit in HMI', + 'index': 1, + 'byte': 0, + 'size': 1, + 'bit': 2, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Fuel Type', + 'index': 1, + 'byte': 0, + 'size': 2, + 'bit': 4, + 'type': 'mask', + '0': 'Gasoline', + '1': 'Diesel', + '2': 'CNG', + '3': 'BEV', + 'items': 4 , + }, + { + 'name': 'NAV Repeater conformance', + 'index': 1, + 'byte': 0, + 'size': 2, + 'bit': 6, + 'type': 'mask', + '0': 'Off', + '1': 'Current', + '2': 'HUD Support', + '3': 'Reserved', + 'items': 4 , + }, + { + 'name': 'Electronic horizon', + 'index': 1, + 'byte': 1, + 'size': 1, + 'bit': 0, + 'type': 'mask', + '0': 'Off', + '1': 'Enabled', + 'items': 2 , + }, + { + 'name': 'Electronic horizon type', + 'index': 1, + 'byte': 1, + 'size': 1, + 'bit': 1, + 'type': 'mask', + '0': 'MPP + Stubs', + '1': 'MPP + First level sub paths', + 'items': 2, + }, + { + 'name': 'Online Traffic', + 'index': 1, + 'byte': 1, + 'size': 2, + 'bit': 4, + 'type': 'mask', + '0': 'Not available', + '1': 'Traffic modem (TPEG)', + '2': 'Online traffic app (TPEG)', + '3': 'Reserved', + 'items': 4 , + }, + { + 'name': 'Internal Gyro', + 'index': 1, + 'byte': 1, + 'size': 1, + 'bit': 6, + 'type': 'mask', + '0': 'Not Present', + '1': 'Present', + 'items': 2 , + }, + { + 'name': 'Gyro on Bus', + 'index': 1, + 'byte': 1, + 'size': 1, + 'bit': 7, + 'type': 'mask', + '0': 'Not Present', + '1': 'Present', + 'items': 2 , + }, + { + 'name': 'Local Hazard Information', + 'index': 213, + 'byte': 2, + 'bit': 0, + 'type': 'mask', + 'size': 2, + 'items': 4, + '0': 'Disabled', + '1': 'IPC Support Only', + '2': 'IPC + HUD Support', + '3': 'reserved', + }, + { + 'name': 'Cloud Based Routing', + 'index': 221, + 'byte': 2, + 'bit': 2, + 'type': 'mask', + 'size': 1, + 'items': 2, + '0': 'Disabled', + '1': 'Enabled', + }, + { 'name': 'Cloud Based Routing Fuel', + 'index': 222, + 'byte': 2, + 'bit': 3, + 'type': 'mask', + 'size': 1, + 'items': 2, + '0': 'Disabled', + '1': 'Enabled', + }, + { 'name': 'Cloud Based Routing Weather', + 'index': 223, + 'byte': 2, + 'bit': 4, + 'type': 'mask', + 'size': 1, + 'items': 2, + '0': 'Disabled', + '1': 'Enabled', + }, + { + 'name': 'Wheel tick frequency', + 'index': 1, + 'byte': 5, + 'bit': 0, + 'type': 'mask', + 'size': 4, + 'items': 8, + '0': '20ms', + '1': '30ms', + '2': '40ms', + '3': '50ms', + '4': '60ms', + '5': '70ms', + '6': '80ms', + '7': 'Reserved', + }, + { + 'name': 'GPS Mount Type', + 'index': 129, + 'byte': 5, + 'bit': 4, + 'size': 8, + 'items': 8 , + 'type': 'mask', + '0': 'Roof Mount', + '1': 'IP Mount (No Heated windshield)', + '2': 'IP Mount (Heated windshield)', + '3': 'Windshield (non Heated)', + '4': 'Windshield (Heated)', + '5': 'Reserved', + '6': 'Reserved', + '7': 'Reserved', + }, + { + 'name': 'Drive Type', + 'index': 132, + 'byte': 6, + 'bit': 0, + 'size': 8, + 'type': 'table', + 'table': '__DT', + }, + { + 'name': 'Vehicle Length', + 'index': 1, + 'byte': 7, + 'size': 24, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 16777215.0, + 'offset': 0, + 'multiplier': 0.01, + 'unit': 'cm', + }, + { + 'name': 'Vehicle height', + 'index': 1, + 'byte': 10, + 'size': 16, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 65535.0, + 'offset': 0, + 'multiplier': 0.01, + 'unit': 'cm', + }, + + + ] + + de05 = [ + { + 'name': 'Front Track', + 'index': 144, + 'byte': 0, + 'size': 16, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 655.35, + 'offset': 0, + 'multiplier': 0.01, + 'unit': 'In', + }, + { + 'name': 'Rear Track', + 'index': 145, + 'byte': 2, + 'size': 16, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 655.35, + 'offset': 0, + 'multiplier': 0.01, + 'unit': 'In', + }, + { + 'name': 'Wheel Base', + 'index': 146, + 'byte': 4, + 'size': 16, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 655.35, + 'offset': 0, + 'multiplier': 0.01, + 'unit': 'In', + }, + ] + + + de06 = [ + { + 'name': 'Vehicle Weight', + 'index': 154, + 'byte': 0, + 'size': 8, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 25500.0, + 'offset': 0, + 'multiplier': 100.0, + 'unit': 'KG', + }, + { + 'name': 'ECO Route Curve', + 'index': 155, + 'byte': 1, + 'size': 8, + 'bit': 0, + 'type': 'mul', + 'min': 1.0, + 'max': 256.0, + 'offset': 1, + 'multiplier': 1.0, + 'unit': 'unitless', + }, + { + 'name': 'Powertrain Efficiency', + 'index': 156, + 'byte': 2, + 'size': 8, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 100.0, + 'offset': 0, + 'multiplier': 0.39215, + 'unit': '%', + }, + { + 'name': 'Regenerative Braking Efficiency Highway', + 'index': 157, + 'byte': 3, + 'size': 8, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 100.0, + 'offset': 0, + 'multiplier': 0.39215, + 'unit': '%', + }, + { + 'name': 'Regenerative Braking Efficiency City', + 'index': 158, + 'byte': 4, + 'size': 8, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 100.0, + 'offset': 0, + 'multiplier': 0.39215, + 'unit': '%', + }, + { + 'name': 'Install Angle of APIM for Accelerometer X', + 'index': 159, + 'byte': 5, + 'size': 16, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 393.21, + 'offset': 0, + 'multiplier': 0.006, + 'unit': 'degrees', + }, + { + 'name': 'Install Angle of APIM for Accelerometer Y', + 'index': 160, + 'byte': 7, + 'size': 16, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 393.21, + 'offset': 0, + 'multiplier': 0.006, + 'unit': 'degrees', + }, + { + 'name': 'Install Angle of APIM for Accelerometer Z', + 'index': 161, + 'byte': 9, + 'size': 16, + 'bit': 0, + 'type': 'mul', + 'min': 0.0, + 'max': 393.21, + 'offset': 0, + 'multiplier': 0.006, + 'unit': 'degrees', + }, + { + 'name': 'Wheel Ticks to Revolution Front: ', + 'index': 162, + 'byte': 11, + 'size': 8, + 'bit': 0, + 'type': 'mul', + 'min': 40.0, + 'max': 295.0, + 'offset': 40, + 'multiplier': 1.0, + 'unit': 'unitless', + }, + { + 'name': 'Wheel Ticks to Revolution Rear', + 'index': 163, + 'byte': 12, + 'size': 8, + 'bit': 0, + 'type': 'mul', + 'min': 40.0, + 'max': 295.0, + 'offset': 40, + 'multiplier': 1.0, + 'unit': 'unitless', + }, + { + 'name': 'Tire Circumference', + 'index': 164, + 'byte': 13, + 'size': 8, + 'bit': 0, + 'type': 'mul', + 'min': 100.0, + 'max': 355.0, + 'offset': 100, + 'multiplier': 1.0, + 'unit': 'cm', + }, + { + 'name': 'Distance from IP to rear axle', + 'index': 165, + 'byte': 14, + 'size': 16, + 'bit': 0, + 'type': 'mul', + 'min': 100.0, + 'max': 65635.0, + 'offset': 100, + 'multiplier': 1.0, + 'unit': 'cm', + }, + ] + + de07 = [ + { + 'name': 'PDC HMI', + 'index': 1, + 'byte': 0, + 'bit': 0, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Off', + '1': 'On', + }, + { + 'name': 'Steering Wheel Angle Sensor', + 'index': 27, + 'byte': 0, + 'bit': 1, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Relative', + '1': 'Absolute', + }, + { + 'name': 'Flank Guard HMI', + 'index': 89, + 'byte': 0, + 'bit': 2, + 'size': 1, + 'items': 2 , + 'type': 'mask', + '0': 'Off', + '1': 'On', + }, + { 'name': 'Front park Aid Adjustable Chimes', + 'index': 193, + 'byte': 0, + 'bit': 3, + 'size': 1, + 'items': 2, + 'type': 'mask', + '0': 'Disabled', + '1': 'Enabled' + }, + { + 'name': 'Rear park Aid Adjustable Chimes', + 'index': 194, + 'byte': 0, + 'bit': 4, + 'size': 1, + 'type': 'mask', + 'items': 2, + '0': 'Disabled', + '1': 'Enabled' + }, + { + 'name': 'APACSI Signal Strategy', + 'index': 219, + 'byte': 0, + 'bit': 5, + 'type': 'mask', + 'size': 2, + 'items': 4, + '0': 'Disabled', + '1': 'Mode 1 (ApaTrgtDist_D_Stat not supported)', + '2': 'Mode 2 (ApaMsgTxt_D_Rq not supported)', + '3': 'Mode 3 (Both not supported)', + }, + { + 'name': 'Parking Assistance', + 'index': 143, + 'byte': 3, + 'bit': 0, + 'size': 8, + 'type': 'table', + 'table': '__PA', + }, + ] + + de08 = [ + ] +#mark + de09 = [ + ] + de10 = [] + unknown = [ + ] + +class ThemeConfig(): + # checks themeconfig + themes = [ + "Ford Classic", #0 + "Ford Timeless", #1 + "Lincoln Classic", #2 + "Lincoln Timeless", #3 + "Ford GT (no longer used in 3.4)" #4 + "?", #5 + "?", + "10L Theme", #7 + "10P Theme" #8 + ] + + config_3_4 = { + "ford-my20": + { + "brand": 0, + "theme": 0, + "animation": -1, + "comment": "Maps to Classic theme but animation might not work" + }, + "ford-my20-2": + { + "brand": 0, + "theme": 0, + "animation": 8, + "comment": "Maps to Classic theme but animation is Vignale Classis" + }, + "ford-my20-3": + { + "brand": 0, + "theme": 1, + "animation": -1, + "comment": "Maps to Classic theme but animation might not work" + }, + "ford-raptor": + { + "brand": 0, + "theme": 1, + "animation": 5, + "comment": None + }, + "ford-mustang": + { + "brand": 0, + "theme": 1, + "animation": 6, + "comment": "Usethemeid is set to 0" + }, + "ford-evo": + { + "brand": 0, + "theme": 0, + "animation": 16, + "comment": None + }, + "ford-shelby": + { + "brand": 0, + "theme": 1, + "animation": 7, + "comment": "Usethemeid is set to 0" + }, + "ford-vignale": + { + "brand": 0, + "theme": 1, + "animation": 8, + "comment": "Usethemeid is set to 0" + }, + "ford-shelbyR": + { + "brand": 0, + "theme": 1, + "animation": 9, + "comment": "Usethemeid is set to 0" + }, + "ford-st": + { + "brand": 0, + "theme": 1, + "animation": 11, + }, + "ford-rs": + { + "brand": 0, + "theme": 1, + "animation": 12, + "comment": "Usethemeid is set to 0" + }, + "ford-my20-former-gt-theme": + { + "brand": 0, + "theme": 4, + "animation": 13, + "comment": "Some versions do not function with this theme!", + "warning": True + }, + "lincoln-U520": + { + "brand": 2, + "theme": 2, + "animation": 20, + "comment": "Marked as obsolete" + }, + "ford-10p-my20": + { + "brand": 0, + "theme": 8, + "animation": -1, + "comment": "Animation change might not work" + }, + "lincoln-my20": + { + "brand": 2, + "theme": 2, + "animation": -1, + "comment": "Marked as obsolete, animation might not work" + }, + "lincoln-blacklabel": + { + "brand": 2, + "theme": 2, + "animation": 3, + "comment": "Usethemeid is set to 3" + }, + "lincoln-presidential": + { + "brand": 2, + "theme": 2, + "animation": 4, + "comment": "Usethemeid is set to 3" + }, + "lincoln-my20": + { + "brand": 2, + "theme": 3, + "animation": -1, + "comment": "Animation might not work, used to be lincoln-next" + }, + "lincoln-my20-2": + { + "brand": 2, + "theme": 3, + "animation": 3, + "comment": "Obsolete is set used to be D544-blacklabel" + }, + "lincoln-continental": + { + "brand": 2, + "theme": 3, + "animation": 14, + "comment": None + }, + "lincoln-10L-my20": + { + "brand": 2, + "theme": 7, + "animation": -1, + "comment": "Animation might not work" + }, + "lincoln-U611": + { + "brand": 2, + "theme": 7, + "animation": 17, + "comment": None + }, + "ford-10P-st": + { + "brand": 0, + "theme": 8, + "animation": 11, + "comment": None + }, + "ford-U625": + { + "brand": 0, + "theme": 0, + "animation": 18, + "comment": None + }, + "ford-10P-U625": + { + "brand": 0, + "theme": 8, + "animation": 18, + "comment": None + }, + "lincoln-CX483": + { + "brand": 2, + "theme": 3, + "animation": 19, + "comment": None + }, + "lincoln-U540": + { + "brand": 2, + "theme": 3, + "animation": 20, + "comment": None + }, + "ford-CX430": + { + "brand": 0, + "theme": 0, + "animation": 23, + "comment": None + }, + } + + @classmethod + def validate(cls, brand, theme, animation, version="3.4"): + matches = [] + if version == "3.4": + for k,v in cls.config_3_4.items(): + if (v['brand'] == brand and v['theme'] == theme and v['animation'] == -1) or (v['brand'] == brand and v['theme'] == theme and v['animation'] == animation): + matches.append("Found theme '%s'. %s" % (k, "" if v['comment'] is None else v['comment'])) + else: + pass + return matches + +class CCTypes(): + ENUM = 1 + FLAG = 2 + VALUE = 3 + +class CCItem(): + name = "" + index = "" + byte = 0 + bit = 0 + size = 0 + itemlist = [] + type = None + + def __init__(self, name, index, byte, bit, size, items=None, type=CCTypes.ENUM): + self.name = name + self.index = index + self.byte = byte + self.bit = bit + self.size = size + if type == CCTypes.ENUM: + self.itemlist = ["Unknown" for i in range(0, 2**size)] + self.itemlist[0] = "Not configured" + if items is not None: + for item in items: + self.itemlist[item[0]] = item[1] + else: + self.itemlist = items if items is not None else [] + self.type = type + + @property + def items(self): + return len(self.itemlist) + + @property + def item(self): + return self.itemlist + + def decode(self, value, other=None, other2=None): + try: + s = "[ %3d ] %s:%s" % (self.index, self.name, (48 - len(self.name)) * " ") + v = value[self.byte] + d = (v >> self.bit) & ((2**self.size) - 1) + if other is None: + if self.type == CCTypes.ENUM: + s = s + "%02X %s" % (d, self.itemlist[d]) + elif self.type == CCTypes.VALUE: + s = s + "%02X [%d]" % (d, d) + elif self.type == CCTypes.FLAG: + s = s + "%02X %s" % (d, "True" if d else "False") + else: + v2 = other[self.byte] + d2 = (v2 >> self.bit) & ((2**self.size) - 1) + if other2 is not None: + v3 = other2[self.byte] + d3 = (v3 >> self.bit) & ((2**self.size) - 1) + if self.type == CCTypes.ENUM: + s = s + "%-56s [%02X] - [%02X] %56s - %-56s [%02X]" % (self.itemlist[d], d, d2, self.itemlist[d2] if d != d2 else "--", self.itemlist[d3] if d != d3 else "--", d3) + elif self.type == CCTypes.VALUE: + s = s + " %02X - %02X - %02X" % (d, d2, d3) + elif self.type == CCTypes.FLAG: + s = s + "%02X %s" % (d, "True" if d else "False") + else: + s = s + "???" + else: + if self.type == CCTypes.ENUM: + s = s + "%-56s [%02X] - [%02X] %56s" % (self.itemlist[d], d, d2, self.itemlist[d2] if d != d2 else "--") + elif self.type == CCTypes.VALUE: + s = s + " %02X - %02X" % (d, d2) + elif self.type == CCTypes.FLAG: + s = s + "%02X %s" % (d, "True" if d else "False") + else: + s = s + "???" + return s + except Exception as e: + + print(e) + return None + + + class ThemeConfig(): # checks themeconfig themes = [