I have a program I wrote in Python that uses the Spotipy library to call the Spotify API to get the user's currently playing song and the tempo of the song in question. It then uses that information, a serial connection, and an Arduino to run some lights.
The problem I'm running into is that I want the program to check the API, with frequency, to see if the song has changed, but each API call takes my network about 0.15 seconds, so after not too many calls it messes up the timing of the lights.
Here is the function that calls the API for the tempo and an example while loop. If you want to see the full project and the complete code, here is the link to the github - https://github.com/eboyce452/lightshow.git:
def check_bpm():
global seconds_per_beat
global current_track
current_track = spotify.current_user_playing_track()
if current_track is None:
seconds_per_beat = 0.5
else:
current_track = json_normalize(current_track)
current_track = str(current_track['item.id'].iloc[0])
features = json_normalize(spotify.audio_features(current_track))
tempo = float(features['tempo'].iloc[0])
seconds_per_beat = 60/tempo
while True:
check_bpm()
pin2.write(1)
time.sleep(seconds_per_beat)
pin2.write(0)
time.sleep(seconds_per_beat)
So what I'm looking for, in a perfect world, is a way to have the check_bpm() function running in the background so that the lights can stay on beat, and then when the song changes, have the loop be interrupted (with like continue or something) and the variable for seconds_per_beat be updated.
I genuinely have no idea if that's even possible or not, so feel free to weigh in on that. But what I'm most curious about is implementing a common form of concurrency so that while the check_bpm() function is waiting for the API call to finish, that it continues with the rest of the while loop so the lights don't get out of sync. I have been reading a lot about asyncio, but I am so unfamiliar with it that any help that can be offered is appreciated.
Thank you so much! Feel free to also check out the github for the project and leave any comments or criticism you'd like.