Python code to monitor if Odrive connection lost

I am wondering if anyone have a suggestion on how to use python code to continuously monitor if the Odrive was disconnected for whatever reason.

odrive.find_any() command will automatically find an Odrive to connect. If using Odrivetool, if the USB was disconnected, it will post a message “oh no odrive0 disappeared”. How can i do the same using python code?

So far I use a thread to constantly pulling with a odrive command for example using .vbus_voltage. If the connection was lost, attributeError will occur then I can use the try: and exception to reconnect or post an error in my application.

Just wonder anyone have a better way to do this?

Thanks!

1 Like

I use a class to control all direct connection to odrive, and catch the error while connectionn lost. If an error occured , I’ll mark it as unavailable

1 Like

Thanks for the suggestion. I am still learning my python and cannot quite figure out how you do what you describe. The method I did isn’t the best and I am having reconnect issue with it. Can you kindly show me how you catch the error? I noticed that once the connection lost (unplug the USB), pulling the odrive class will return "??? ". I think i can use ._remote_attributes.items() and see if the dictionary return ‘???’, but this look like a very inefficient way of doing this. Can the fibre object return something to indicate connection lost? Thanks again

def _check_odrive_link(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        if not self._is_connected:
            return 0
        try:
            return func(self, *args, **kwargs)
        except (AttributeError, ChannelBrokenException):
            self._is_connected = False
            return 0

    return wrapper

then you can use
@_check_odrive_link
def myfunction(self, arg1, arg2):
return XXX

1 Like

zjqtzzc, thanks for sharing.

I also found 2 other methods to do this. 1st one is utilizing the odrivetools code. To use the same feature that odrivetools already got to detect when the USB is disconnected, first import “odrive.shell”.Then use the code as below,

import odrive
import odrive.shell
from fibre.utils import *

log=Logger()
token1=Event()
od=odrive.find_any()
odrive.shell.did_discover_device(od,log,token1)

when usb cable is diconnected, “Oh no odrive0 disappeard” will be print on the terminal and odrive object will be delete. but this method only to unsubscribe to odrive object as odrivetool does

2nd method is subscribe directly to the odrive channel broken signal. Below is the example of the code I try.

def USBerror():
print(“Device disconnected”)

od=odrive.find_any()
od.channel._channel_broken.subscribe(USBerror)

When the USB is disconnected, the function USBerror will be call.

Caution:
I also discover the fibre library that using libusb did not catch usb error code number 19 and 32 in windows 10 environment. Above code only work on linux. I think the problem is not in odrive or fibre, but within the libusb that utilizing different hardware driver for the USB connection.

i tried the _channel_broken.suscribe but got an error about a protected member

Below is the correct code. The double underscore was removed by the post editor automatically.

od=odrive.find_any()
image

**USBerror is the function of your choice

1 Like