canopen icon indicating copy to clipboard operation
canopen copied to clipboard

Exception in thread can.notifier

Open TWignites opened this issue 4 years ago • 4 comments

Dear all, the python-canopen package works great in different projects for me (Windows and Linux). By now I have a problem when starting an external program. Configuration is Raspberry pi4 with Raspbian Buster, Python3.7, Spyder3.3.3, python-can 3.3.4, canopen 1.2.1. Program works fine (makes nothing, just checks the network by timer) until button is pressed an external program is called. Exception arises in thread can.notifier for bus "socketcan channel 'can0'": with OSError: [Errno 100]. Starting the network again works but I do not understand the reason for loosing the network. I stripped down the program and it would be great if anybody could help me.

from PyQt5 import QtCore, QtWidgets
import os, sys
import canopen
import logging

class GUI(QtWidgets.QMainWindow):    

    def __init__(self, *args, **kwargs):
        super(GUI,self).__init__()
        self.pushButton_Editor = QtWidgets.QPushButton(self)
        self.pushButton_Editor.setText("open geany")
        self.pushButton_Editor.clicked.connect(lambda: os.popen("geany settings.ini"))

        timer_error = QtCore.QTimer(self)
        timer_error.setInterval(5000)  # ms
        timer_error.timeout.connect(self.CheckCANerror)
        timer_error.start()

    def CheckCANerror(self):
        global network
        try:
            if network.check() == None:
                logging.info('CANbus oK')
        except:
            logging.warning('Error CANbus: RESTART')
            os.system('sudo ip link set can0 down')
            os.system('sudo ip link set can0 type can bitrate 250000 triple-sampling on restart-ms 100')
            os.system('sudo ip link set can0 up')
            try:
                network.connect(channel='can0',                    # CANbus öffnen
                            bustype='socketcan', 
                            bitrate=250000)
            except:
                logging.error('CANbus: RESTART ERROR')

def startup():
    logging.basicConfig(level=logging.INFO)
    
    os.system('sudo ip link set can0 down')
    os.system('sudo ip link set can0 type can bitrate 250000 triple-sampling on restart-ms 100')
    os.system('sudo ip link set can0 up')

    global network
    network = canopen.Network()                        # Network adressieren
    network.connect(channel='can0',                    # CANbus öffnen
                    bustype='socketcan', 
                    bitrate=250000)

    app = QtWidgets.QApplication(sys.argv)
    win = GUI()
    win.show()
    sys.exit(app.exec_())

startup()
`

TWignites avatar Nov 07 '21 15:11 TWignites

I see this error as well if the network is coming up and down under fault conditions. Seems like the exception is not caught correctly in that thread. @christiansandberg any advice on how to handle this correctly?

RTNETLINK answers: Connection timed out
Exception in thread can.notifier for bus "socketcan channel 'can1'":
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/can/interfaces/socketcan/socketcan.py", line 498, in capture_message
    cf = sock.recv(CANFD_MTU)
OSError: [Errno 100] Network is down
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/dist-packages/can/notifier.py", line 103, in _rx_thread
    msg = bus.recv(self.timeout)
  File "/usr/local/lib/python3.9/dist-packages/can/bus.py", line 83, in recv
    msg, already_filtered = self._recv_internal(timeout=time_left)
  File "/usr/local/lib/python3.9/dist-packages/can/interfaces/socketcan/socketcan.py", line 621, in _recv_internal
    msg = capture_message(self.socket, get_channel)
  File "/usr/local/lib/python3.9/dist-packages/can/interfaces/socketcan/socketcan.py", line 501, in capture_message
    raise can.CanError("Error receiving: %s" % exc)
can.CanError: Error receiving: [Errno 100] Network is down

edcloudcycle avatar Jul 15 '22 12:07 edcloudcycle

It seems to not be very well documented but you should be able to create your own can.Listener class implementing on_error() and adding it to network.listeners.

If the method does not raise the error will be ignored.

christiansandberg avatar Jul 15 '22 13:07 christiansandberg

Sorry, I was wrong. The reader thread will terminate anyway. But maybe you can restart the communication using that method.

christiansandberg avatar Jul 15 '22 13:07 christiansandberg

Hi Christian, Thanks for the response. I realised I was not on the latest version of python-can and upgrading to 4.0.0 and canopen 2.0.0 seems to prevent this problem. Instead I get a stderr message that says: Transfer aborted by client with code 0x05040000 Which seems benign and a lot better than an unhandled exception killing a thread I don't control. :)

Thanks for all your hardwork on these libraries. They are awesome.

Ed

edcloudcycle avatar Jul 15 '22 18:07 edcloudcycle