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

async @after() handler crashes with TypeError #117

Closed
OrangeTux opened this issue Sep 18, 2020 · 0 comments · Fixed by #118
Closed

async @after() handler crashes with TypeError #117

OrangeTux opened this issue Sep 18, 2020 · 0 comments · Fixed by #118

Comments

@OrangeTux
Copy link
Contributor

OrangeTux commented Sep 18, 2020

Release v0.7.0 introduces a bug when executing @after() handler that are marked with the async keyword. Thanks @shirley-li-powerflex for reporting it.

Here a code sample demonstrating the problem:

import asyncio
import logging
from datetime import datetime

try:
    import websockets
except ModuleNotFoundError:
    print("This example relies on the 'websockets' package.")
    print("Please install it by running: ")
    print()
    print(" $ pip install websockets")
    import sys
    sys.exit(1)

from ocpp.routing import on, after
from ocpp.v16 import ChargePoint as cp
from ocpp.v16.enums import Action, RegistrationStatus
from ocpp.v16 import call_result

logging.basicConfig(level=logging.INFO)


class ChargePoint(cp):
    @on(Action.BootNotification)
    def on_boot_notitication(self, charge_point_vendor: str, charge_point_model: str, **kwargs):
        return call_result.BootNotificationPayload(
            current_time=datetime.utcnow().isoformat(),
            interval=10,
            status=RegistrationStatus.accepted
        )

    @after(Action.BootNotification)
    async def after_boot_notification(self, *args, **kwargs):
        pass

async def on_connect(websocket, path):
    """ For every new charge point that connects, create a ChargePoint instance
    and start listening for messages.

    """
    charge_point_id = path.strip('/')
    cp = ChargePoint(charge_point_id, websocket)

    await cp.start()


async def main():
    server = await websockets.serve(
        on_connect,
        '0.0.0.0',
        9000,
        subprotocols=['ocpp1.6']
    )

    await server.wait_closed()


if __name__ == '__main__':
    try:
        # asyncio.run() is used when running this example with Python 3.7 and
        # higher.
        asyncio.run(main())
    except AttributeError:
        # For Python 3.6 a bit more code is required to run the main() task on
        # an event loop.
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
        loop.close()

When ran using v0.7.0 the following stracktrace is generated:

Traceback (most recent call last):
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/websockets/server.py", line 191, in handler
    await self.ws_handler(self, path)
  File "examples/v16/central_system.py", line 44, in on_connect
    await cp.start()
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 126, in start
    await self.route_message(message)
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 144, in route_message
    await self._handle_call(msg)
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 222, in _handle_call
    asyncio.ensure_future(response)
  File "/home/developer/.pyenv/versions/3.8.0/lib/python3.8/asyncio/tasks.py", line 673, in ensure_future
    raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required

Non-async @after() handlers are not affected.

OrangeTux referenced this issue Sep 18, 2020
In order to avoid the following warning:

```
/.../lib/python3.8/site-packages/ocpp/charge_point.py:184:
DeprecationWarning: "@coroutine" decorator is deprecated
since Python 3.8, use "async def" instead
response = await asyncio.coroutine(handler)(**snake_case_payload)
```
OrangeTux added a commit that referenced this issue Sep 18, 2020
The response of the handler was passed to `asyncio.ensure_future()`
and that resulted in a `TypeError`.

```
Traceback (most recent call last):
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/websockets/server.py", line 191, in handler
    await self.ws_handler(self, path)
  File "examples/v16/central_system.py", line 44, in on_connect
    await cp.start()
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 126, in start
    await self.route_message(message)
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 144, in route_message
    await self._handle_call(msg)
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 222, in _handle_call
    asyncio.ensure_future(response)
  File "/home/developer/.pyenv/versions/3.8.0/lib/python3.8/asyncio/tasks.py", line 673, in ensure_future
    raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required
```

Fixes: #117
ajmirsky pushed a commit to ajmirsky/ocpp that referenced this issue Nov 26, 2024
The response of the handler was passed to `asyncio.ensure_future()`
and that resulted in a `TypeError`.

```
Traceback (most recent call last):
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/websockets/server.py", line 191, in handler
    await self.ws_handler(self, path)
  File "examples/v16/central_system.py", line 44, in on_connect
    await cp.start()
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 126, in start
    await self.route_message(message)
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 144, in route_message
    await self._handle_call(msg)
  File "/home/developer/projects/tmh-ocpp/.env/lib/python3.8/site-packages/ocpp/charge_point.py", line 222, in _handle_call
    asyncio.ensure_future(response)
  File "/home/developer/.pyenv/versions/3.8.0/lib/python3.8/asyncio/tasks.py", line 673, in ensure_future
    raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required
```

Fixes: mobilityhouse#117
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

1 participant