def __call__(self, lines): """ Main function accepts a list of raw strings from the car, split by lines """ # ---------------------------- preprocess ---------------------------- # Non-hex (non-OBD) lines shouldn't go through the big parsers, # since they are typically messages such as: "NO DATA", "CAN ERROR", # "UNABLE TO CONNECT", etc, so sort them into these two lists: obd_lines = [] non_obd_lines = [] for line in lines: line_no_spaces = line.replace(' ', '') if isHex(line_no_spaces): obd_lines.append(line_no_spaces) else: non_obd_lines.append( line) # pass the original, un-scrubbed line # ---------------------- handle valid OBD lines ---------------------- # parse each frame (each line) frames = [] for line in obd_lines: frame = Frame(line) # subclass function to parse the lines into Frames # drop frames that couldn't be parsed if self.parse_frame(frame): frames.append(frame) # group frames by transmitting ECU # frames_by_ECU[tx_id] = [Frame, Frame] frames_by_ECU = {} for frame in frames: if frame.tx_id not in frames_by_ECU: frames_by_ECU[frame.tx_id] = [frame] else: frames_by_ECU[frame.tx_id].append(frame) # parse frames into whole messages messages = [] for ecu in frames_by_ECU: # new message object with a copy of the raw data # and frames addressed for this ecu message = Message(frames_by_ECU[ecu]) # subclass function to assemble frames into Messages if self.parse_message(message): # mark with the appropriate ECU ID message.ecu = self.ecu_map.get(ecu, ECU.UNKNOWN) messages.append(message) # ----------- handle invalid lines (probably from the ELM) ----------- for line in non_obd_lines: # give each line its own message object # messages are ECU.UNKNOWN by default messages.append(Message([Frame(line)])) return messages
def __call__(self, lines): """ Main function accepts a list of raw strings from the car, split by lines """ # ---------------------------- preprocess ---------------------------- # Non-hex (non-OBD) lines shouldn't go through the big parsers, # since they are typically messages such as: "NO DATA", "CAN ERROR", # "UNABLE TO CONNECT", etc, so sort them into these two lists: obd_lines = [] non_obd_lines = [] for line in lines: line_no_spaces = line.replace(' ', '') if isHex(line_no_spaces): obd_lines.append(line_no_spaces) else: non_obd_lines.append(line) # pass the original, un-scrubbed line # ---------------------- handle valid OBD lines ---------------------- # parse each frame (each line) frames = [] for line in obd_lines: frame = Frame(line) # subclass function to parse the lines into Frames # drop frames that couldn't be parsed if self.parse_frame(frame): frames.append(frame) # group frames by transmitting ECU # frames_by_ECU[tx_id] = [Frame, Frame] frames_by_ECU = {} for frame in frames: if frame.tx_id not in frames_by_ECU: frames_by_ECU[frame.tx_id] = [frame] else: frames_by_ECU[frame.tx_id].append(frame) # parse frames into whole messages messages = [] for ecu in sorted(frames_by_ECU.keys()): # new message object with a copy of the raw data # and frames addressed for this ecu message = Message(frames_by_ECU[ecu]) # subclass function to assemble frames into Messages if self.parse_message(message): # mark with the appropriate ECU ID message.ecu = self.ecu_map.get(ecu, ECU.UNKNOWN) messages.append(message) # ----------- handle invalid lines (probably from the ELM) ----------- for line in non_obd_lines: # give each line its own message object # messages are ECU.UNKNOWN by default messages.append(Message([Frame(line)])) return messages