Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Execution stops #26

Open
lubbifo opened this issue Nov 24, 2020 · 5 comments
Open

Execution stops #26

lubbifo opened this issue Nov 24, 2020 · 5 comments

Comments

@lubbifo
Copy link

lubbifo commented Nov 24, 2020

Hi there,

I use your python library for Openhab integration. Frequently it happens, that this external program gets stuck. I then see the following in the process list:

user  20821  0.0  0.0   1468   244 ?        S    12:11   0:00 sh -c /mijia/mijia_temp read a4:c1:38:41:xxxx
user  20823  0.4  0.3  13936  6492 ?        S    12:11   0:02 python3 /mijia/mijia_temp read a4:c1:38:41:xxxx

It stays there forever.... This is how I use the library (derived from your demo code):

client = lywsd02.Lywsd02Client(mac, notification_timeout=30.0)
data = client.data
print('{:.1f}C {}%'.format(data.temperature,data.humidity))

The device I am using is this:

https://goodereader.com/blog/uploads/images/Screenshot_2020-05-27-C9-86-20-OFF-Newest-Xiaomi-Mijia-Bluetooth-Temperature-humidity-2-Wireless-Smart-Electric-Digital....png

I am using library version 0.0.9 on Python 3.7.3

I understand, that the connectivity to the device is noisy and unreliable. However, the code should return a result or an error after the timeout, but not stuck.

Am I doing anything wrong? Any ideas?

P.S.: "timeout 40 lywsdo2.python ...." is a good workaround

@h4
Copy link
Owner

h4 commented Dec 3, 2020

Very strange. Client should fail after 30 sec timeout. I'll try to get similar device and check.

@CeKl
Copy link

CeKl commented Apr 15, 2021

Hi there,

i also tried to work with the LYWSD03MMC like @lubbifo describes. For about 2 - 4 hours everything works without a problem in a Python script, similar to the example. However, for some reason not yet found, the program freezes. So I have the same problem.

I used the libary in version 0.0.9 with Python 3.8.6 on a Raspberry Pi 3+

Maybe by now there are some ideas or a way to get to the exception, which is normally supposed to show up after 30 seconds as described?
If it works though, the libary functions top.

@CeKl
Copy link

CeKl commented Apr 17, 2021

As a workaround I am currently using signal to abort the request after a set time.

import signal
from lywsd02 import Lywsd02Client

device_mac = 'AA:BB:CC:DD:EE:FF'

class TimeoutException(Exception):
    pass

def timeout_handler(signum, frame):
    raise TimeoutException

signal.signal(signal.SIGALRM, timeout_handler)

while True:
    signal.alarm(20)
    try:
        client = Lywsd02Client(device_mac, notification_timeout=5.0)
        with client.connect():
            data = client.data
            print(data.temperature)
            print(data.humidity)
            print(client.battery)

    except TimeoutException:
        continue

    except Exception as e:
        print(e)

    else:
        signal.alarm(0)

So far I have not found why the bluepy-helper freezes as a process or does nothing more at full CPU load. Maybe this helps someone until the problem is solved.

@a-lost-shadow
Copy link

I've been running into the same problem. Looking at the code, I noticed that Lywsd02Client.connect() call does not provide a timeout when it calls Peripheral.connect() in the bluepy library. In that case, it looks like bluepy will send a message to begin the connection, and then go into an infinite loop waiting for a response. So I think this is what's causing the failures we're seeing.

I'm going to try and get a remote debugger setup on my program so I can confirm my suspicion.

@a-lost-shadow
Copy link

Turns out it was locking up in the call to getCharacteristic(). Here's the code path that was failing after I added a timeout:

File "/home/iot_debug/mijia/monitor.py", line 76, in read_sensor
  return sensorConnection.data, datetime.datetime.now()
File "/home/iot_debug/mijia/lywsd02/client.py", line 71, in data
  self._get_sensor_data()
File "/home/iot_debug/mijia/lywsd02/client.py", line 159, in _get_sensor_data
  self._subscribe(UUID_DATA, self._process_sensor_data)
File "/home/iot_debug/mijia/lywsd02/client.py", line 182, in _subscribe
  ch = self._peripheral.getCharacteristics(uuid=uuid, timeout=5.0)[0]
File "/home/iot_debug/mijia/bluepy/btle.py", line 539, in getCharacteristics
  rsp = self._getResp('find', timeout)

This ran successfully for 30 hours before I started to poke it again (previously I was seeing failures in the 2-6 hour range). I'm pretty sure I saw 6 timeouts over that duration, but I accidentally ate the timeout exception without properly logging it.

Unfortunately to get this to work, I needed to modify bluepy. I'm going to run a longer term test before submitting a pull request to bluepy. I'll submit a pull request here if/when the bluepy one is accepted.

In the meantime, you can see my changes to bluepy and lywsd02 at:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants