def main(): can_interface = 'can1' bus = Bus(can_interface) try: while True: Message = bus.recv(0.0) if Message: check_rx(Message.arbitration_id, Message.data[0]) except KeyboardInterrupt: bus.shutdown()
def canListener(pipe): data = {} bus = Bus(env.bus) while 1: frame = bus.recv(timeout=0.005) data[hex(frame.arbitration_id)] = frame.data if (pipe.poll(timeout=0)): # flush out the pipe from any flags for writing while pipe.poll(timeout=0): pipe.recv() pipe.send(data) pipe.close() return # execution really should not get here
class can_bus(): def __init__(self): self.bus = Bus('can0', bustype='socketcan_ctypes') self.rx_buff = [] self.tx_buff = [] def transmit(self, data): msg = can.Message(arbitration_id=0x000, data=data, extended_id=False) try: self.bus.send(msg) print("Message sent on {}".format(self.bus.channel_info)) except can.CanError: print("Message NOT sent") def recieve(self, timeout=None): try: msg = self.bus.recv(timeout=1.0) print("Message recieved on {}".format(self.bus.channel_info)) print msg except can.CanError: print("Message NOT received")
def clean(*args): print(''.join(out)) sys.exit(0) if __name__ == '__main__': signal(SIGTERM, clean) count = 0 if (send_recv == "send"): message = can.Message(extended_id=False, is_error_frame=False, arbitration_id=id_in, data=[data] * length) while 1: sleep(uniform(0.001, 0.1)) bus.send(message) count += 1 out[8] = str(count) elif (send_recv == "receive"): print() while 1: print(bus.recv()) count += 1 out[8] = str(count)
class IBSInterface(can.Listener): """ This class defines the methods for a minimal ISOBUS CF. This means address claiming procedures (part 5) and diagnostics (part 12). Other interfaces inherit from this class to implement specific parts, such as IBSVTInterface (part 6). """ def __init__(self, interface, channel): can.rc['interface'] = interface can.rc['channel'] = channel log.info('Opening CAN connection on {0}'.format(can.rc['channel'])) self.bus = Bus(bitrate=250000) self.periodic_tasks = list() self._rxHandlers = list() #Have to use a separate bus object, otherwise WaitForIsobusmessage does not work #self.notifier = can.Notifier(Bus(), [self]) def __del__(self): self.bus.shutdown() def on_message_received(self, mesg): #TODO: Check 'listening' flag, if listening, store in queue # Change 'WaitForIBSMessage' accordingly, so we don't have to call recv on bus # Then we need a 'Start listening' and 'StopListening' + flushqueue method ibsid = IBSID.FromCANID(mesg.arbitration_id) log.debug('Rx Mesg PGN {pgn:04X} SA {sa:02X} DA {da:02X}'.format( pgn=ibsid.pgn, sa=ibsid.sa, da=ibsid.da)) #TODO: Smarter filters, SA, DA, PGN, muxbyte? for handler in self._rxHandlers: if pgn in handler.pgnlist: handler.RxMessage(ibsid, mesg.data) def AddRxHandler(self, handler): self._rxHandlers.append(handler) def AddPeriodicMessage(self, ibsid, contents, period): # For socketcan_native, bit 32 (MSb) needs to be set for extended ID # Is fixed in latest python-can though! log.debug( 'Adding periodic message ID : 0x{mesgid:08X} period {T}'.format( mesgid=ibsid.GetCANID(), T=period)) msg = can.Message(arbitration_id=(ibsid.GetCANID() | (1 << 31)), data=contents, extended_id=True) self.periodic_tasks.append( can.send_periodic(can.rc['channel'], msg, period)) def StopPeriodicMessage(self, ibsid): # For socketcan_native, bit 32 (MSb) needs to be set for extended ID # Is fixed in latest python-can though! for periodMsg in self.periodic_tasks: if periodMsg.can_id == (ibsid.GetCANID() | (1 << 31)): log.debug( 'Stopping periodic message ID : 0x{mesgid:08X}'.format( mesgid=ibsid.GetCANID())) self.periodic_tasks.remove(periodMsg) periodMsg.stop() break def ModifyPeriodicMessage(self, ibsid, newContent): # For socketcan_native, bit 32 (MSb) needs to be set for extended ID # Is fixed in latest python-can though! msg = can.Message(arbitration_id=(ibsid.GetCANID() | (1 << 31)), data=newContent, extended_id=True) for periodMsg in self.periodic_task: if periodMsg.can_id == canid: periodMsg.modify_data(self, msg) break def SendRequestAddressClaim(self, sa): log.debug('Sending Request Address Claim') self.SendRequest(sa, da=SA_GLOBAL, reqPGN=PGN_ADDRCLAIM) def SendAddressClaim(self, ibsName, sa): log.debug('Sending Address claim for name {:016X}'.format(ibsName)) candata = NumericValue(ibsName).AsLEBytes(8) self._SendIBSMessage(PGN_ADDRCLAIM, SA_GLOBAL, sa, candata) def SendRequest(self, sa, da, reqPGN): self._SendIBSMessage(PGN_REQUEST, sa, da, NumericValue(reqPGN).AsLEBytes(3)) ## PROTECTED FUNCTIONS def _SendCANMessage(self, canid, candata): if len(candata) <= 8: msg = can.Message(arbitration_id=canid, data=candata, extended_id=True) try: self.bus.send(msg) except can.CanError: log.warning('Error sending message') def _WaitForIBSMessage(self, pgn, fromsa, tosa, muxByte, maxtime=3.0): # TODO: Also accept incoming TP session # TODO: Can we miss messages because we start listening too late? received = False data = [RESERVED] * 8 # Dummy data for when nothing is received starttime = time.time() matchID = IBSID(da=tosa, sa=fromsa, pgn=pgn, prio=6) while not (received): mesg = self.bus.recv(0.5) if mesg is not None: receivedID = IBSID.FromCANID(mesg.arbitration_id) if (receivedID.pgn == matchID.pgn and receivedID.da == matchID.da and receivedID.sa == matchID.sa and mesg.data[0] == muxByte): received = True data = mesg.data break if (time.time() - starttime) > maxtime: log.debug('Timeout waiting for CAN ID {canid:08X}'.format( canid=matchID.GetCANID())) break return received, data def _SendIBSMessage(self, pgn, da, sa, data, prio=6): if len(data) <= 8: canid = IBSID(da, sa, pgn, prio).GetCANID() self._SendCANMessage(canid, data) elif len(data) <= 1785: self._SendTPMessage(pgn, da, sa, data) elif len(data) <= 117440505: self._SendETPMessage(pgn, da, sa, data) else: log.warning('ERROR : CAN message too large to send') def _SendTPMessage(self, pgn, da, sa, data): log.debug('(TP) Request starting TP for {n} bytes'.format(n=len(data))) tpcm_id = IBSID(da, sa, pgn=PGN_TP_CM, prio=6) tpdt_id = IBSID(da, sa, pgn=PGN_TP_DT, prio=7) # Send RTS rts_control = 0x10 nr_of_packets = int(math.ceil(len(data) / 7.0)) rts_data = ([rts_control] + NumericValue(len(data)).AsLEBytes(2) + [nr_of_packets, RESERVED] + NumericValue(pgn).AsLEBytes(3)) log.debug( '(TP) Sending RTS for PGN {0} : {1} bytes in {2} packets'.format( pgn, len(data), nr_of_packets)) self._SendCANMessage(tpcm_id.GetCANID(), rts_data) # Check the CTS #FIXME: Only send min(nrOfPackets,maxPackets), what to do if less? [received, ctsdata] = self._WaitForIBSMessage(0xEC00, da, sa, 0x11) if received: log.debug('(TP) Received CTS for max {0} packets, next packet {1}'. format(ctsdata[1], ctsdata[2])) else: return False # Pack with 0xFF if len(data) % 7 > 0: data = data + list([RESERVED] * (7 - (len(data) % 7))) # Send bytes for seqN in range(nr_of_packets): log.debug('(TP) Send package {n}'.format(n=seqN + 1)) startByte = seqN * 7 self._SendCANMessage(tpdt_id.GetCANID(), [seqN + 1] + data[startByte:startByte + 7]) # sleep 1 msec, otherwise hardware buffer gets full! time.sleep(0.001) def _SendETPMessage(self, pgn, da, sa, data): log.debug( '(ETP) Request starting ETP for {n} bytes'.format(n=len(data))) etpcm_id = IBSID(da, sa, PGN_ETP_CM, prio=6) etpdt_id = IBSID(da, sa, PGN_ETP_DT, prio=7) mesg_size = len(data) # Send RTS rts_control = 0x14 totalPackets = int(math.ceil(len(data) / 7.0)) log.debug("(ETP) Sending {0} bytes in {1} packets".format( len(data), totalPackets)) rts_data = ([rts_control] + NumericValue(mesg_size).AsLEBytes(4) + NumericValue(pgn).AsLEBytes(3)) self._SendCANMessage(etpcm_id.GetCANID(), rts_data) # Pack data with 0xFF to multiple of 7 if len(data) % 7 > 0: data = data + list([RESERVED] * (7 - (len(data) % 7))) # Setup for the data transfer nextPacket = 1 maxSentPackets = 0 done = False while not (done): # TODO: What is the time out for this one? [received, ctsdata] = self._WaitForIBSMessage(0xC800, da, sa, 0x15) if received: nextPacket = NumericValue.FromLEBytes(ctsdata[2:5]).Value() maxSentPackets = ctsdata[1] log.debug( "(ETP) Received CTS for max {0} packets, next packet {1}". format(maxSentPackets, nextPacket)) else: log.warning('(ETP) Wait for CTS timed out') break packetOffset = nextPacket - 1 nPackets = min(maxSentPackets, totalPackets - packetOffset) log.debug( '(ETP) Sending {0} packets with packet offset {1}'.format( nPackets, packetOffset)) log.debug('(ETP) bytes[{0} - {1}]'.format( packetOffset * 7, packetOffset * 7 + nPackets * 7 - 1)) dpoData = ([0x16] + [nPackets] + NumericValue(packetOffset).AsLEBytes(3) + NumericValue(pgn).AsLEBytes(3)) self._SendCANMessage(etpcm_id.GetCANID(), dpoData) for n in range(nPackets): startByte = (n * 7) + (packetOffset * 7) # Send send data[n * 7 + dataoffset: n* 7 +7 + dataoffset] self._SendCANMessage(etpdt_id.GetCANID(), [n + 1] + data[startByte:startByte + 7]) # If it is the last packet, quit the loop if (n + nextPacket) >= totalPackets: done = True break time.sleep(0.001)
class CanAdapter(object): def __init__(self, can_interface): can.rc['interface'] = 'socketcan_ctypes' if can_interface is None: can_interface = 'can0' self._can_interface = can_interface if not self.status(): raise IOError("CAN Bus not available") self._bus = Bus(self._can_interface) self._bitrate = 500000 if self._bus is None: raise IOError("Can't find CAN bus interface") self._rcv_thread_quit = False self._rcv_thread = None self._rcv_queue = queue.Queue(maxsize=1024) def status(self): ip_link_cmd = "ip link | grep " + self._can_interface can0_link = subprocess.check_output(ip_link_cmd, shell=True).decode("utf-8") states = re.sub('[!<>]', '', can0_link.split()[2]).split(',') return 'UP' in states def start(self, callback): if not self._rcv_thread: self._callback = callback self._rcv_thread = threading.Thread(target=self._process_receive) self._rcv_thread_quit = False self._rcv_thread.start() def stop(self): if self._rcv_thread: self._rcv_thread_quit = True self._rcv_thread.join(5.0) self.join_failed = self._rcv_thread.is_alive() self._rcv_thread = None def send(self, id, data): Message.extended_id = True Message.is_remote_frame = False Message.id_type = 1 Message.is_error_frame = False Message.arbitration_id = id Message.dlc = len(data) Message.data = data try: self._bus.send(Message) return True except: return False def receive(self, block=False, timeout=None): try: msg = self._rcv_queue.get(block, timeout) except: msg = None return msg def flush(self): while self.receive() is not None: continue def _process_receive(self): while not self._rcv_thread_quit: msg = self._bus.recv(0.25) # seconds if msg: try: self._callback(msg) self._rcv_queue.put(msg, False) except: pass
class CAN_Main(object): def __init__(self): self.currentSpeed = 0 self.previousSpeed = 0 self.updateSpeed = False self.currentVoltage = 0 self.previousVoltage = 0 self.updateVoltage = False self.leftBlindSpot = False self.leftBottomBlindSpot = False self.centerBottombBlindSpot = False self.rightBottomBlindSpot = False self.rightBlindSpot = False self.overVoltageWarning = False self.underVoltageWarning = False self.overTemperatureWarning = False self.underTemperatureWarning = False self.overCurrentWarning = False self.underCurrentWarning = False def initializeInstances(self): self.bus = Bus(can_interface,can_filters=FILTER_DICTIONARY_LIST) self.can_tools = CAN_Opener.Can_Opener() def pollBus(self): try: msg = self.bus.recv(timeout=10) self.process_CAN_message(msg) except: print("TODO m: We need to catch this, yo") raise def process_CAN_message(self, pCan_frame): self.message_select(pCan_frame) def message_select(self, pCAN_frame): if(pCAN_frame.arbitration_id == 0x100): self.message_one(pCAN_frame.data) elif(pCAN_frame.arbitration_id == 0x200): self.message_two(pCAN_frame.data) elif(pCAN_frame.arbitration_id == 0x300): self.message_three(pCAN_frame.data) elif(pCAN_frame.arbitration_id == 0x400): self.message_four(pCAN_frame.data) else: pass def shiftData(self, pValue, pShiftPlaces): return pValue>>pShiftPlaces def message_one(self, data): #Engine Signals msg_one_bits = self.can_tools.pack_data(data) ''' TODO m: update to EV self.set_engine_coolant_temp(self.shiftData(data[0], 1)) self.set_engine_torque(data[1]) self.set_engine_RPM(data[3]*256 + data[2]) self.set_throttle_percent(self.shiftData(data[4], 1)) ''' def message_two(self, data): #Warnings msg_two_bits = self.can_tools.pack_data(data) ''' TODO m: update to EV self.set_warning_ess_overtemp(self.can_tools.shift_mask(0, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_fuel_level_low(self.can_tools.shift_mask(1, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_glv_cockpit_brb(self.can_tools.shift_mask(2, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_glv_soc_low(self.can_tools.shift_mask(3, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_motor_over_temp(self.can_tools.shift_mask(4, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_transmission_failure(self.can_tools.shift_mask(5, 1, msg_two_bits, ONE_BIT_MASK)) ''' def message_three(self, data): #Electrical Systems ''' TODO m: update for EV self.set_ess_soc(self.shiftData(data[0], 1)) self.set_ess_voltage(data[1]) ''' def message_four(self, data): #Control msg_four_bits = self.can_tools.pack_data(data) '''