Timeout on get_players() following onPlay notification
Closed this issue · 2 comments
Hello,
I'm just trying a (primitive) script to understand PyKodi usage. The notify_OnPlay()
and notify_OnStop()
functions below do work. At first, I was only having them print the data argument they receive, and that worked without issue.
I then thought to have the notify_onPlay()
function proceed to query Kodi regarding what Player started, via an await on get_players()
. The ultimate goal would then be to get further information about the item that just started playback.
That get_players()
await is timing out however.
Commented out in the onPlay code below is also another kodi.ping()
attempt. If that's uncommented, it times out as well.
In producing the output below, Kodi playback was started and stopped via a separate DLNA controller.
I am using
- PyKodi 0.2.1 and
- jsonrpc-websocket 1.2.1
under Python 3.8.3 on Windows 10. The version of the Kodi instance I'm connecting to is in the output below.
I am new to the whole asyncio approach, so perhaps something is broken about my basic approach? A pointer to set me on the right path would then be appreciated.
Fundamentally, should a Notification (receive) function be able to invoke other coroutines that issue JSON-RPC requests?
Thanks for your help!
Matt
Output (newlines added for clarity):
Waiting for kodi.ping
response = True
properties = {'name': 'Kodi', 'version': {'major': 18, 'minor': 8, 'revision': '02c2dd21befe52facee9bebdd37b0d159e416369', 'tag': 'stable'}}
Initial players = []
OnPlay data = {'item':
{'album': 'Hugo Original Score',
'artist': ['Howard Shore'],
'title': 'The Thief',
'track': 1, 'type': 'song'},
'player': {'playerid': 0, 'speed': 1}}
Invoking get_players...
("Error calling method 'Player.GetActivePlayers': Transport Error", TimeoutError())
Traceback (most recent call last):
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\site-packages\jsonrpc_websocket\jsonrpc.py", line 128, in wait
await self._event.wait()
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\asyncio\locks.py", line 309, in wait
await fut
asyncio.exceptions.CancelledError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\site-packages\jsonrpc_websocket\jsonrpc.py", line 42, in send_message
response = await pending_message.wait(self._timeout)
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\site-packages\jsonrpc_websocket\jsonrpc.py", line 129, in wait
return self._response
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\site-packages\async_timeout\__init__.py", line 45, in __exit__
self._do_exit(exc_type)
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\site-packages\async_timeout\__init__.py", line 92, in _do_exit
raise asyncio.TimeoutError
asyncio.exceptions.TimeoutError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\site-packages\jsonrpc_base\jsonrpc.py", line 90, in async_receive_request
result = await handler(*args, **kwargs)
File "webs4.py", line 18, in notify_OnPlay
players = await info.kodi.get_players()
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\site-packages\pykodi\kodi.py", line 400, in get_players
return await self._server.Player.GetActivePlayers()
File "C:\Users\513277\AppData\Local\Programs\Python\Python38\lib\site-packages\jsonrpc_websocket\jsonrpc.py", line 48, in send_message
raise TransportError('Transport Error', message, exc)
jsonrpc_base.jsonrpc.TransportError: ("Error calling method 'Player.GetActivePlayers': Transport Error", TimeoutError())
OnStop data = {'end': False, 'item':
{'album': 'Hugo Original Score',
'artist': ['Howard Shore'],
'title': 'The Thief',
'track': 1,
'type': 'song'}}
Script
from pykodi import get_kodi_connection, Kodi
import asyncio
import signal
# Create an "empty" object for use as shared state
info = type('', (), {})()
loop = asyncio.get_event_loop()
async def notify_OnPlay(sender, data):
global info
print("OnPlay data = ", data)
#print(" Trying a new ping.")
#await info.kodi.ping()
#print(" Returned from that ping.")
print(" Invoking get_players...")
players = await info.kodi.get_players()
print(" players = ", players)
async def notify_OnStop(sender, data):
global info
print("OnStop data = ", data)
async def main():
global info
kc = get_kodi_connection(host="10.0.0.188", port=8080, ws_port=9090, username="kodi", password="")
await kc.connect()
kodi = Kodi(kc)
info.kodi = kodi
print("Waiting for kodi.ping")
response = await info.kodi.ping()
print("response = ", response)
properties = await info.kodi.get_application_properties(["name", "version"])
print("properties = ", properties)
players = await info.kodi.get_players()
print("Initial players = ", players)
kc.server.Player.OnPlay = notify_OnPlay
kc.server.Player.OnStop = notify_OnStop
if __name__ == "__main__":
signal.signal(signal.SIGINT, signal.SIG_DFL)
loop.create_task(main())
loop.run_forever()
I'm not entirely sure how the underlying json-rpc async package is handling this, but I think that it's fair to assume that you shouldn't call kodi again from within a callback. Maybe try to schedule a task?
Closing due to no activity