def start(self, device, node_id): if node_id < 1 or node_id > 127: raise CANopenException('Node identifier needs to be in the range of 1 to 127.') print('Starting CANopen device with Node ID %d(0x%02X)' % (node_id, node_id)) self.event.start() self.driver = SocketCAN(device=device) self.receiver.start() self.timer.start() self.nmt = NMT(canopen=self, node_id=node_id) # Bootup message data = bytearray() data.append(self.nmt.operatingState) self.send(0x700 + self.nmt.node_id, data) self.nmt.operatingState = self.nmt.OPERATIONAL
class CANopen: def __init__(self): self.driver = None self.event = Event() self.receiver_alive = True self.receiver = Thread(target=self.run) self.timer = Timer() self.nmt = None def start(self, device, node_id): if node_id < 1 or node_id > 127: raise CANopenException('Node identifier needs to be in the range of 1 to 127.') print('Starting CANopen device with Node ID %d(0x%02X)' % (node_id, node_id)) self.event.start() self.driver = SocketCAN(device=device) self.receiver.start() self.timer.start() self.nmt = NMT(canopen=self, node_id=node_id) # Bootup message data = bytearray() data.append(self.nmt.operatingState) self.send(0x700 + self.nmt.node_id, data) self.nmt.operatingState = self.nmt.OPERATIONAL def send(self, node_id, data): self.driver.send(node_id, data) def register(self, handler): self.event += handler def run(self): while self.receiver_alive: try: # TODO do not block, then we can not terminate message = self.driver.recv() # TODO use new thread to emit events self.event(message=message) except CANopenException: print('Problem receiving data.') def stop(self): print('Stopping CANopen device') self.nmt.delete() self.timer.stop() self.receiver_alive = False self.driver.close() self.receiver.join() self.event.stop() def SDOupload(self, node_id, index, subindex, type, value): # only expedited yet if len(value) > 4: raise CANopenException('Can not upload more than 4 bytes currently.') data = bytearray() # command byte data.append(0x23 | (4 - len(data)) << 2) # index LSB data.append(index & 0xff) data.append((index >> 8) & 0xff) # sub-index data.append(subindex) # data TODO LSB data.append(value) receive = SDOResponse() self.event += receive.receive() try: self.send(0x580 + node_id, data) return receive.get() finally: self.event -= receive.receive() def SDOread(self, node_id, index, subindex, type): return 0