IanHarvey / bluepy

Python interface to Bluetooth LE on Linux
Other
1.58k stars 490 forks source link

bluepy helper keeps crashing #267

Open polsa opened 6 years ago

polsa commented 6 years ago

Hi all,

in my project I run a scan for one second in a loop. This worked very well since February. Now since monday I face an issue where the bluepy helper seems to crash and bluepy is no longer functioning. This happens after a couple of minutes.

In my python script I get the following exception:

Exception in thread BLEScannerThread:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inn
    self.run()
  File "pible_scanner.py", line 177, in run
    self.scan(1.0)
  File "pible_scanner.py", line 188, in scan
    found_devices = self.scanner.scan(timeout)
  File "/usr/local/lib/python2.7/dist-packages/bluepy/btle.py", line 6
    self.stop()
  File "/usr/local/lib/python2.7/dist-packages/bluepy/btle.py", line 6
    self._mgmtCmd(self._cmd()+"end")
  File "/usr/local/lib/python2.7/dist-packages/bluepy/btle.py", line 2
    rsp = self._waitResp('mgmt')
  File "/usr/local/lib/python2.7/dist-packages/bluepy/btle.py", line 3
    raise BTLEException(BTLEException.DISCONNECTED, "Device disconnect
BTLEException: Device disconnected

And in top I can see that there is no more bluepy helper running. As I said the code was working before so I wonder what has happened. Any ideas?

Thanks, Filip

sterwen commented 5 years ago

I have a similar problem on Debian 4.9. The application can run fine foe hours but then it starts to crash repeatedly with an error like the one above or simply ERRNO 32 Broken Pipe inidicating the helper has crashed.

KnightYusuf commented 5 years ago

I have the same problem ! ERRNO 32 Broken Pipe

victorlapshev commented 4 years ago

Any updates?

JsBergbau commented 4 years ago

I'm author of https://github.com/JsBergbau/MiTemperature2 and I encounter a similiar problem. bluepy-helper crashes on a PI Zero W after some time. Sometimes a few hours, sometimes longer. Quite difficult to track. bluepy-helper then uses 100 % CPU and connection to this MAC address even with gatttool is not possible anymore. Connection to another BLE device with gatttool is possible. The current solution I have is to kill bluepy-helper and data can be read again.

JsBergbau commented 4 years ago

I have traced down the issue a bit. It hangs at the connection establishment. So I've implemented a watchdog thread. After one minute unconnected it fetches the pid of bluepy-helper from the process tree, kills and program continues.

grzegorzjj commented 4 years ago

@JsBergbau Could You write a bit more about this watchdog? I'm suffering from this issue and planned to use monit daemon to kill the process if it has more than 15%, but matbe Your solution is better. I'm using of course Your script to read from BLE termometer. [ I'm not so familiar with python.... ]

JsBergbau commented 3 years ago

Hi

I use this code

def watchDog_Thread():
    global unconnectedTime
    global connected
    global pid
    while True:
        logging.debug("watchdog_Thread")
        logging.debug("unconnectedTime : " + str(unconnectedTime))
        logging.debug("connected : " + str(connected))
        logging.debug("pid : " + str(pid))
        now = int(time.time())
        if (unconnectedTime is not None) and ((now - unconnectedTime) > 60): #could also check connected is False, but this is more fault proof
            pstree=os.popen("pstree -p " + str(pid)).read() #we want to kill only bluepy from our own process tree, because other python scripts have there own bluepy-helper process
            logging.debug("PSTree: " + pstree)
            try:
                bluepypid=re.findall(r'bluepy-helper\((.*)\)',pstree)[0] #Store the bluepypid, to kill it later
            except IndexError: #Should not happen since we're now connected
                logging.debug("Couldn't find pid of bluepy-helper")
            os.system("kill " + bluepypid)
            logging.debug("Killed bluepy with pid: " + str(bluepypid))
            unconnectedTime = now #reset unconnectedTime to prevent multiple killings in a row
        time.sleep(5)

started by

watchdogThread = threading.Thread(target=watchDog_Thread)
watchdogThread.start()

in my script. From a quick view it should work in your script without any modifications.

grzegorzjj commented 3 years ago

I believe it is alreaddy in my script and unfortunately does not work in 100%. I got daily 2-3 hanging bluepy-helper processes that warms up the raspberry pi chipset to >85 C deg. and take 100% of processor

I wrote some script ( called sys_usage ) that is run form monit daemon called by:

check process bluepy-helper matching "bluepy-helper" if exist then exec "/root/sys_usage"

and the script ( it uses binary calculator - in debian One should add the package [ sudo apt-get install bc ] ):

!/bin/bash

LAVG=/usr/bin/uptime | /usr/bin/awk '{print $10}' | /usr/bin/cut -d "," -f 1 LOG_DATA=/bin/date +'%Y-%m-%d %H:%M:%S' MAX_LAVG=0.5 PROCESS_NAME="bluepy-helper" LOG_PATH=/var/log/script_bluepy.log

put Your path here for log.

echo "$LOG_DATA LAVG: current: $LAVG , max. accept: $MAX_LAVG" >> $LOG_PATH

if (( $(echo "$LAVG > $MAX_LAVG" |/usr/bin/bc -l) )); then /usr/bin/killall $PROCESS_NAME 2>/dev/null echo "$LOG_DATA <$0> LAVG: $LAVG exceeds $MAX_LAVG - running killall" >> $LOG_PATH fi

sleep 90

LAVG=/usr/bin/uptime | /usr/bin/awk '{print $10}' | /usr/bin/cut -d "," -f 1 if (( $(echo "$LAVG > $MAX_LAVG" |/usr/bin/bc -l) )); then /usr/bin/killall $PROCESS_NAME 2>/dev/null echo "$LOG_DATA LAVG: $LAVG exceeds $MAX_LAVG - running killall [2nd]" >> $LOG_PATH fi

Maybe it helps someone. For me it works 100% - 10 days without hanging bluepy-helper. It can even br run from a cron every 2-5 minutes. But then it does not check existence of bluepy-helper process in system.