question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TimeoutError in AppDaemon

See original GitHub issue

I use the service spotcast.start in my AppDaemon alarm clock.

Since the service takes some time (>10sec) and does not return any results early, AppDaemon throws a timeout error, even though the service gets executed correctly.

My current solution is to except the possible timeout errors and ignore it.

try:
    self.call_service(
        "spotcast/start",
        entity_id="media_player.uberall",
        uri="spotify:playlist:1F60OIQoIgpXCrKJny7C8z"
    )
except (concurrent.futures._base.TimeoutError, asyncio.exceptions.TimeoutError):
    pass

Edit: But this does not work always apparently. I found this in my logs.

2020-06-06 15:23:20 ERROR (MainThread) [homeassistant.core] Error executing service: <ServiceCall spotcast.start (c:524fbd2e9196417f8237856ec24354f1): entity_id=media_player.uberall, uri=spotify:playlist:3roeMsWrNcImq6wGBJb4j8, shuffle=True, offset=0, random_song=False, force_playback=False, repeat=off>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1269, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1292, in _execute_service
    await self._hass.async_add_executor_job(handler.func, service_call)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/spotcast/__init__.py", line 178, in start_casting
    spotify_cast_device.startSpotifyController(access_token, expires)
  File "/config/custom_components/spotcast/__init__.py", line 267, in startSpotifyController
    sp.launch_app()
  File "/usr/local/lib/python3.7/site-packages/pychromecast/controllers/spotify.py", line 85, in launch_app
    "Timeout when waiting for status response from Spotify app"
pychromecast.error.LaunchError: Timeout when waiting for status response from Spotify app

Starting the service from the UI does work always. The errors seem to appear only in combination with AppDaemon.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:11 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
fondbergcommented, Jun 11, 2020

I’m sorry but I can’t think of anything that can help you with the time to get the token. Released 3.1.1 which could be one problem. Try that, if that doesn’t help read below

regarding the long boot times; I think you have some dependency problem. Try removing spotcast using HACS and then make sure it is gone from custom_components. Reboot your entire PI.

Now install spotcast again and restart.

0reactions
provinziocommented, Jun 11, 2020

tl;dr at the bottom.

I did some debugging steps:

I started by removing spotcast and spotify integration.

  • Boot time: <1min

Fresh install spotcast with HACS.

  • Boot time: ~10min
  • No specific core log entries besides Setup of default_config is taking over 10 seconds
  • Music startup time after service start from ui: 45sec

I use a Raspberry Pi 3B with Raspbian and supervised Hassio.

Is there a way to look at integrations logs like with addons? Edit: Ah easier than I thought, one can use the Logger integration.

Edit2: Bumped spotipy to 2.12.0, might solve #93

  • Boot up time is now fine with < 1min:
  • Music startup time after service start from ui: ~40sec

Edit3: I entered a wrong entity_id and it took 39 sec. to realize that device_name is empty.

Edit4: I profiled the code and will look into it.

2020-06-11 12:16:28 DEBUG (SyncWorker_16) [custom_components.spotcast] start_casting
2020-06-11 12:16:28 DEBUG (SyncWorker_16) [custom_components.spotcast] get_account_credentials
2020-06-11 12:16:28 DEBUG (SyncWorker_16) [custom_components.spotcast] get_spotify_token
2020-06-11 12:17:01 DEBUG (SyncWorker_16) [custom_components.spotcast] getSpotifyConnectDeviceId
2020-06-11 12:17:06 DEBUG (SyncWorker_16) [custom_components.spotcast] SpotifyCastDevice::__init__
2020-06-11 12:17:06 DEBUG (SyncWorker_16) [custom_components.spotcast] SpotifyCastDevice::getChromecastDevice
2020-06-11 12:17:06 DEBUG (SyncWorker_16) [custom_components.spotcast] cast info: ChromecastInfo(host='192.168.178.22', port=8009, service='Google-Home-Mini-<ID>._googlecast._tcp.local.', uuid='<ID>', model_name='Google Home Mini', friendly_name='Wohnzimmer')
2020-06-11 12:17:06 INFO (SyncWorker_16) [pychromecast] Querying device status
2020-06-11 12:17:06 DEBUG (SyncWorker_16) [custom_components.spotcast] Found cast device: Chromecast('192.168.178.22', port=8009, device=DeviceStatus(friendly_name='Wohnzimmer', model_name='Google Home Mini', manufacturer='Google Inc.', uuid='<ID>', cast_type='audio'))
2020-06-11 12:17:06 DEBUG (SyncWorker_16) [custom_components.spotcast] SpotifyCastDevice::startSpotifyController
2020-06-11 12:17:06 INFO (SyncWorker_16) [pychromecast.controllers] Receiver:Launching app CC32E753
2020-06-11 12:17:10 DEBUG (SyncWorker_16) [custom_components.spotcast] SpotifyCastDevice::getSpotifyDeviceId
2020-06-11 12:17:10 DEBUG (SyncWorker_16) [custom_components.spotcast] play
2020-06-11 12:17:10 DEBUG (SyncWorker_16) [custom_components.spotcast] Version: 3.1.0, playing URI: spotify:playlist:1w47Q047w6znBJBuaOPL9H on device-id: fa9f7342e68d99adc4b9692a825c0fc9
2020-06-11 12:17:10 DEBUG (SyncWorker_16) [custom_components.spotcast] Playing context uri using context_uri for uri: "spotify:playlist:1w47Q047w6znBJBuaOPL9H" (random_song: False)
2020-06-11 12:17:13 DEBUG (SyncWorker_16) [custom_components.spotcast] Turning repeat on

Edit5: spotify_token takes most of the time (33 sec). Since the Code is really small i included it directly into the code and profiled it too. I realised that it has some unrequired requirements and imports ( lxml, bs4) which could be removed. Removing them does not change the required time.

Here is the profiling

2020-06-11 12:44:46 DEBUG (SyncWorker_15) [custom_components.spotcast] start_casting
2020-06-11 12:44:46 DEBUG (SyncWorker_15) [custom_components.spotcast] get_account_credentials
2020-06-11 12:44:46 DEBUG (SyncWorker_15) [custom_components.spotcast] get_spotify_token
2020-06-11 12:44:46 DEBUG (SyncWorker_15) [custom_components.spotcast] start_session
2020-06-11 12:44:46 DEBUG (SyncWorker_15) [custom_components.spotcast] start_session session get
2020-06-11 12:45:19 DEBUG (SyncWorker_15) [custom_components.spotcast] start_session raise for status
2020-06-11 12:45:19 DEBUG (SyncWorker_15) [custom_components.spotcast] start_session decode
2020-06-11 12:45:19 DEBUG (SyncWorker_15) [custom_components.spotcast] start_session json load
2020-06-11 12:45:19 DEBUG (SyncWorker_15) [custom_components.spotcast] get_spotify_token session started

I am unsure why the session.get() command requires that much time. Unfortnatuly I have only a small knowledge about requests and am not sure how to tweak them.

I ran the code on my local computer without speed issues, but running it on the raspberry pi requires 32 sec. Any ideas?

Edit6: While testing my swap ran into 100%. So I raised it from 100 MB to 2 GB. Nothing different, I also disabled it. No change.

Running the following takes more time to start the speedtest than on my desktop pc and returns also a slower bandwidth (25-30 Mbit/s vs. 50 Mbit/s). Not sure why…

pip3 install speedtest-cli
speedtest-cli

Edit7: My pi seems to have problems with ipv6. A solution for this could solve the problem?

ping6 -c 3 google.com
PING google.com(fra15s22-in-x0e.1e100.net (2a00:1450:4001:81f::200e)) 56 data bytes
--- google.com ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 92ms

I forced spotify_token to use IPv4 with https://stackoverflow.com/questions/33046733/force-requests-to-use-ipv4-ipv6. which makes the request resolve quickly.

So I added the following at the top of spotcast/__init__.py

# BUGFIX only allow IPv4 connections
import socket
import requests.packages.urllib3.util.connection as urllib3_cn
def allowed_gai_family():
	"""
	 https://github.com/shazow/urllib3/blob/master/urllib3/util/connection.py
	"""
	family = socket.AF_INET
	# if urllib3_cn.HAS_IPV6:
	# 	family = socket.AF_INET6 # force ipv6 only if it is available
	return family
urllib3_cn.allowed_gai_family = allowed_gai_family
# END BUGFIX

tl;dr:

  • Found a bug (see #98)
  • May solved the problem with long boot up time #93 (see other issue for suggestion)
  • The long time to start spotcast with my raspberry pi comes mainly from spotify_token’s request to spotify. When I force to use IPv4 (instead of IPv6) the request is fast. I am not sure, why my pi does not support IPv6. Suggestions/Help welcome.

Since my problem has only slightly to do with spotcast, the issue might be closed if you have nothing else to say @fondberg

Read more comments on GitHub >

github_iconTop Results From Across the Web

Asyncio TimeoutError in AD4 · Issue #852 · AppDaemon ...
(perhaps related to #848) I have an app that calls a service at random intervals between 5 and 60 minutes: from random import...
Read more >
Timeout error? - AppDaemon - Home Assistant Community
Hey all, Started getting this a time out error recently. It is happening when calling to lock or unlock my august smart locks...
Read more >
Change Log — AppDaemon 4.2.1 documentation
Released new AppDaemon Admin User Interface; Added support for passing a list ... Fixed issue whereby the wrong the wrong timeout error was...
Read more >
concurrent.futures._base.TimeoutError- AppDaemon - Home ...
I find myself, writing a lot of code like this, because some (mostly external) service in hass is taking a lot of time…...
Read more >
home-assistant - Bountysource
Created 2 years ago in AppDaemon/appdaemon with 9 comments. ... line 441, in result raise TimeoutError() concurrent.futures._base.TimeoutError.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found