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

Asyncio errors in bleak #65

Open
sqall01 opened this issue Oct 3, 2022 · 10 comments
Open

Asyncio errors in bleak #65

sqall01 opened this issue Oct 3, 2022 · 10 comments

Comments

@sqall01
Copy link

sqall01 commented Oct 3, 2022

Hi,

I do not know if this issue is related to some of the already open ones since I do not use eq3cli. However, the underlying issue could be the same.

Since the switch to bleak, I can no longer connect to my thermostats. I can simply reproduce the error by executing:

from eq3bt import Thermostat
test = Thermostat("00:1a:22:12:26:ee")
test.update()

The output is the following:

>>> from eq3bt import Thermostat

>>> test = Thermostat("00:1a:22:12:26:ee")

>>> test.update()
Task exception was never retrieved
future: <Task finished name='Task-9' coro=<BleakConnection.on_notification() done, defined at /home/sqall/syncfolder/projekte/alertR/thermostat_service/venv_bleak/lib/python3.8/site-packages/eq3bt/bleakconnection.py:77> exception=TypeError("unsupported operand type(s) for +: 'BleakGATTCharacteristicBlueZDBus' and 'int'")>
Traceback (most recent call last):
  File "/home/sqall/syncfolder/projekte/alertR/thermostat_service/venv_bleak/lib/python3.8/site-packages/eq3bt/bleakconnection.py", line 119, in make_request
    self._loop.run_until_complete(self.wait_for_response(timeout))
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/home/sqall/syncfolder/projekte/alertR/thermostat_service/venv_bleak/lib/python3.8/site-packages/eq3bt/bleakconnection.py", line 101, in wait_for_response
    await asyncio.wait_for(self._notifyevent.wait(), timeout)
  File "/usr/lib/python3.8/asyncio/tasks.py", line 494, in wait_for
    return fut.result()
  File "/usr/lib/python3.8/asyncio/locks.py", line 309, in wait
    await fut
RuntimeError: Task <Task pending name='Task-7' coro=<Event.wait() running at /usr/lib/python3.8/asyncio/locks.py:309> cb=[_release_waiter(<Future pendi...8e2f51700>()]>)() at /usr/lib/python3.8/asyncio/tasks.py:429]> got Future <Future pending> attached to a different loop

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/sqall/syncfolder/projekte/alertR/thermostat_service/venv_bleak/lib/python3.8/site-packages/eq3bt/bleakconnection.py", line 80, in on_notification
    handle = handle + 1
TypeError: unsupported operand type(s) for +: 'BleakGATTCharacteristicBlueZDBus' and 'int'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sqall/syncfolder/projekte/alertR/thermostat_service/venv_bleak/lib/python3.8/site-packages/eq3bt/eq3btsmart.py", line 217, in update
    self._conn.make_request(PROP_WRITE_HANDLE, value)
  File "/home/sqall/syncfolder/projekte/alertR/thermostat_service/venv_bleak/lib/python3.8/site-packages/eq3bt/bleakconnection.py", line 119, in make_request
    self._loop.run_until_complete(self.wait_for_response(timeout))
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/home/sqall/syncfolder/projekte/alertR/thermostat_service/venv_bleak/lib/python3.8/site-packages/eq3bt/bleakconnection.py", line 101, in wait_for_response
    await asyncio.wait_for(self._notifyevent.wait(), timeout)
  File "/usr/lib/python3.8/asyncio/tasks.py", line 494, in wait_for
    return fut.result()
  File "/usr/lib/python3.8/asyncio/locks.py", line 309, in wait
    await fut
RuntimeError: Task <Task pending name='Task-7' coro=<Event.wait() running at /usr/lib/python3.8/asyncio/locks.py:309> cb=[_release_waiter(<Future pendi...8e2f51700>()]>)() at /usr/lib/python3.8/asyncio/tasks.py:429]> got Future <Future pending> attached to a different loop

I am running a xubuntu 20.04 machine with Python 3.8.10 (default, Jun 22 2022, 20:18:18) and have the following packages installed in my python environment:

Package       Version
------------- -------
async-timeout 4.0.2  
bleak         0.18.1 
click         8.1.3  
construct     2.10.68
dbus-fast     1.17.0 
pip           20.0.2 
pkg-resources 0.0.0  
python-eq3bt  0.2    
setuptools    44.0.0 
wheel         0.34.2

Everything works fine if I downgrade to version 0.1.12 which uses bluepy.

Well, since I thought this was a problem in bleak, I got involved in this issue hbldh/bleak#946 However, the maintainer says this is a problem in the asyncio loop of the python-eq3bt library (see here: hbldh/bleak#946 (comment) ).

Thanks!

@rytilahti
Copy link
Owner

Hey,

would you mind checking if the current git master is working for you? The only change to the released 0.2 is that the event loop should be now only created when none already exists (#58).

Alternatively, as a stopgap solution you could pass the wanted connection class to use bluepy or gattlib instead of bleak, see https://github.com/rytilahti/python-eq3bt/blob/master/eq3bt/eq3cli.py#L33-L46 how the eq3cli does it.

@sqall01
Copy link
Author

sqall01 commented Oct 4, 2022

Hey,

I checked out the master branch and executing everything again. But it still does not work.

>>> from eq3bt import Thermostat
>>> test = Thermostat("00:1a:22:12:26:ee")
>>> test.update()
Task exception was never retrieved
future: <Task finished name='Task-9' coro=<BleakConnection.on_notification() done, defined at /home/sqall/Desktop/test/python-eq3bt/eq3bt/bleakconnection.py:82> exception=TypeError("unsupported operand type(s) for +: 'BleakGATTCharacteristicBlueZDBus' and 'int'")>
Traceback (most recent call last):
  File "/home/sqall/Desktop/test/python-eq3bt/eq3bt/bleakconnection.py", line 124, in make_request
    self._loop.run_until_complete(self.wait_for_response(timeout))
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/home/sqall/Desktop/test/python-eq3bt/eq3bt/bleakconnection.py", line 106, in wait_for_response
    await asyncio.wait_for(self._notifyevent.wait(), timeout)
  File "/usr/lib/python3.8/asyncio/tasks.py", line 494, in wait_for
    return fut.result()
  File "/usr/lib/python3.8/asyncio/locks.py", line 309, in wait
    await fut
RuntimeError: Task <Task pending name='Task-7' coro=<Event.wait() running at /usr/lib/python3.8/asyncio/locks.py:309> cb=[_release_waiter(<Future pendi...5fa9d06d0>()]>)() at /usr/lib/python3.8/asyncio/tasks.py:429]> got Future <Future pending> attached to a different loop

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/sqall/Desktop/test/python-eq3bt/eq3bt/bleakconnection.py", line 85, in on_notification
    handle = handle + 1
TypeError: unsupported operand type(s) for +: 'BleakGATTCharacteristicBlueZDBus' and 'int'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sqall/Desktop/test/python-eq3bt/eq3bt/eq3btsmart.py", line 217, in update
    self._conn.make_request(PROP_WRITE_HANDLE, value)
  File "/home/sqall/Desktop/test/python-eq3bt/eq3bt/bleakconnection.py", line 124, in make_request
    self._loop.run_until_complete(self.wait_for_response(timeout))
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/home/sqall/Desktop/test/python-eq3bt/eq3bt/bleakconnection.py", line 106, in wait_for_response
    await asyncio.wait_for(self._notifyevent.wait(), timeout)
  File "/usr/lib/python3.8/asyncio/tasks.py", line 494, in wait_for
    return fut.result()
  File "/usr/lib/python3.8/asyncio/locks.py", line 309, in wait
    await fut
RuntimeError: Task <Task pending name='Task-7' coro=<Event.wait() running at /usr/lib/python3.8/asyncio/locks.py:309> cb=[_release_waiter(<Future pendi...5fa9d06d0>()]>)() at /usr/lib/python3.8/asyncio/tasks.py:429]> got Future <Future pending> attached to a different loop

@sqall01
Copy link
Author

sqall01 commented Oct 6, 2022

Alternatively, as a stopgap solution you could pass the wanted connection class to use bluepy or gattlib instead of bleak, see https://github.com/rytilahti/python-eq3bt/blob/master/eq3bt/eq3cli.py#L33-L46 how the eq3cli does it.

Thanks for this pointer. I did so in my code and it works. However, there is a minor "inconvenience". The code looks now like this:

import eq3bt
from eq3bt.connection import BTLEConnection
[...]
  # Give manually the connection class as per default bleak is used which does not work
  self._thermostat = eq3bt.Thermostat(self._mac, connection_cls=BTLEConnection)

The class BTLEConnection and BleakConnection are not exposed via the __init__.py and thus have to be accessed manually. It would be nice to expose them also via the __init__.py since you give the possibility in the Thermostat class to pass them as argument.

@nica-f
Copy link

nica-f commented Nov 28, 2022

I am using this module within HomeAssist and can confirm that the 'async error' prevents the HomeAssist plugin from working. With gattlib I can make it work most of the time (often get timeouts too) from CLI but I can not control which backend the HomeAssist plugin uses.

@peslun
Copy link

peslun commented Nov 29, 2022

I can confirm, that BLEAK connection is still not working with python-eq3bt installed from master branch.

eq3cli --mac 00:1A:22:0E:10:F2
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-10' coro=<BleakConnection.on_notification() done, defined at /usr/local/lib/python3.10/site-packages/eq3bt/bleakconnection.py:77> exception=TypeError("unsupported operand type(s) for +: 'BleakGATTCharacteristicBlueZDBus' and 'int'")>
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/eq3bt/bleakconnection.py", line 80, in on_notification
    handle = handle + 1
TypeError: unsupported operand type(s) for +: 'BleakGATTCharacteristicBlueZDBus' and 'int'
Traceback (most recent call last):
  File "/usr/local/bin/eq3cli", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1635, in invoke
    rv = super().invoke(ctx)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/eq3bt/eq3cli.py", line 51, in cli
    ctx.invoke(state)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/eq3bt/eq3cli.py", line 199, in state
    click.echo(dev)
  File "/usr/local/lib/python3.10/site-packages/click/utils.py", line 258, in echo
    out: t.Optional[t.Union[str, bytes]] = str(message)
  File "/usr/local/lib/python3.10/site-packages/eq3bt/eq3btsmart.py", line 108, in __str__
    self._conn.mac, self.target_temperature, self.mode_readable, away_end
  File "/usr/local/lib/python3.10/site-packages/eq3bt/eq3btsmart.py", line 320, in mode_readable
    if mode.MANUAL:
AttributeError: 'NoneType' object has no attribute 'MANUAL'

However, it works well with backend bluepy.

eq3cli --mac 00:1A:22:0E:10:F2 --backend bluepy
[00:1A:22:0E:10:F2] Target 20.0 (mode: manual (20.0C) dst, away: no)
Locked: False
Batter low: False
Window open: False
Window open temp: 12.0
Window open time: 0:15:00
Boost: False
Current target temp: 20.0
Current comfort temp: 21.0
Current eco temp: 17.0
Current temp offset: 0.0
Current mode: manual (20.0C) dst
Valve: 0

As reported elsewhere, downgrading to 0.1.12 works:

pip install https://github.com/rytilahti/python-eq3bt/archive/refs/tags/0.1.12.zip
eq3cli --mac 00:1A:22:0E:10:F2
[00:1A:22:0E:10:F2] Target 20.0 (mode: manual (20.0C) dst, away: no)
Locked: False
Batter low: False
Window open: False
Window open temp: 12.0
Window open time: 0:15:00
Boost: False
Current target temp: 20.0
Current comfort temp: 21.0
Current eco temp: 17.0
Current temp offset: 0.0
Current mode: manual (20.0C) dst
Valve: 0

I have two valves, both paired and trusted in bluetoothctl. One has firmware 1.46, the other 1.20. Both show the exact same behavior (bleak not working, bluepy working).

It would be wonderful to have these valves working again in home-assistant (runs in docker on DietPi - variant of Debian). It stubbornly upgrades to 0.2.

Do you need some additional info? I am ready to do some testing.

@dbuezas
Copy link
Contributor

dbuezas commented Nov 29, 2022

I feel bad for mining this repo with links to my fork, but it looks like it's hard to find:

https://github.com/dbuezas/eq3btsmart

This one works in the latest home assistant versions and adds a bunch of improvements and goodies

@peslun
Copy link

peslun commented Nov 29, 2022

I understand dbuezas, but I am a simple user that needs that his TRV works. The breaking change in 2022.8 or .9 made me very unhappy.

Your fork works and so does finally also my setup in HA again, thanks.

@rytilahti
Copy link
Owner

@sqall01 you are right that the API is not the nicest, the problem is the optional dependencies I didn't want to force everyone to install. Constructing a nicer API would have required much more effort than I was willing to put into this project, especially as I'm not actively using these ever since I relinquished mine excluding one test device to you :-)

@dbuezas feel free to create an issue (and/or a PR to the README) to inform homeassistant users about the state of affairs and a link to your custom integration. Also, if you wish to take over the maintainership of this project, or the homeassistant integration, I'd be very thankful for that. If you do not aim to get your custom integration to be included in the homeassistant core, please let me know.

Also, if either of you wants to have a single pre-1.20 fw device, let me know and I'll find a way to get it to you.

@dbuezas
Copy link
Contributor

dbuezas commented Dec 12, 2022

@rytilahti thank you! Yes, I intend to get it to the core once BTProxies start working, but my fork can't do cli at all so this repo should stay here :).
Regarding the device, I do need another one, but their price has increased a lot lately, you can probably sell it for 50€

@sqall01
Copy link
Author

sqall01 commented Dec 15, 2022

@rytilahti it is unfortunate that you do not use the thermostats anymore. I have them all around my apartment and am quite happy with them. The heat control is self-build, but works like a charm. And funny thing is: I build it out of fun. But it actually now saved more money in heating costs than the hardware costed me while I was building it 😆

@dbuezas what the actual fuck? I just checked the prices for new thermostats. Around 75€ from the vendor. I should have bought more of them when they were around 20€ as they were when I bought them.

dbuezas added a commit to dbuezas/python-eq3bt that referenced this issue Dec 19, 2022
Added notice to HA users and link to the custom component as suggested here rytilahti#65 (comment)
rytilahti pushed a commit that referenced this issue Dec 19, 2022
Added notice to HA users and link to the custom component as suggested here #65 (comment)
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

5 participants