Mopidy state and control via jsonrpclib (Python)

Hi!

I’m working on a python script that controls mopidy on a Raspberry Pi 1. I’m wondering which way is best to go. Currently I’m using jsonrpclib to add songs, play, seek and so on and it pretty muck works fine. But I also want to monitor the state of mopidy and wonder how to make this most efficiently. Right now I’m doing it like this:
server.core.playback.get_state()
where server is:
def getServer():
ip = os.environ.get(‘MOPIDYSERVER’, ‘127.0.0.1:6680’)
return jsonrpclib.Server(‘http://{}/mopidy/rpc’.format(ip))

But it seems like it takes too much resources to call the get_state function every second - sometimes the other calls to mopidy seem to drown in the flood of requests to mopidy. Is there a more efficient way to do this?

Hi @ac34, to monitor the state of mopidy I think listen to events of mopidy it is more efficient that be continuously polling. Events inform about the changes in track, state, volume, etc… and are described in CoreListener API.

To do that you can give a try to mopidy-json-client. It is a package I’m writing to solve similar issues. The simplest code to use it woult be like:

from mopidy_json_client import MopidyClient, SimpleListener

class MyScript(SimpleListener):

         def __init__(self):      
               # Instantiate Mopidy Client
                self.mopidy = MopidyClient(server_addr='localhost:6680',
                                           event_handler=self.on_event)

         def playback_state_changed(self, old_state, new_state):     
                self.state = new_state
                print('> Playback state changed to ', self.state)

You can also make orders to the server using pyhton functions, like self.mopidy.playback.play() or self.mopidy.tracklist.add(uris=[%%LIST_OF_URIS%%])

At examples/demo_cli.py there is a more detailed example of use to control and listen to events.

Thanks a lot! Since I’m super new to programming I don’t fully get how to implement this but I’ll read on a bit on Python. :slight_smile:
Right now I just have a main while loop and a bunch of functions…

I tried with git clone but got the following error:

git clone git@github.com:ismailof/mopidy-json-client
Klonar till "mopidy-json-client"...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Then I tried git clone https://github.com/ismailof/mopidy-json-client.git
and the download completed. However, nothing happened when i ran pip install mopidy-json-client (I aborted the process after several minutes of no output).

I’m also willing to try the pykka way as in
https://docs.mopidy.com/en/latest/extensiondev/#example-frontend

but I’m completely lost. Could anyone give a hint for setting up an environment with a main loop and an example call to core and corelistener respectively?

The error messages accurately describes why the git clone git@github.com:blah didn’t work, you need to have a github login to clone over SSH. Cloning over HTTPS avoids this. The github getting started documentation should explain this and more.

If you want to install via pip the files you just downloaded then you need to point to the files. If you just specify a package name (such as mopidy-json-client) then it’ll try and download files from pypi. But in this case there are none available to download. So ensuring you are already in the mopidy-json-client directory then just do pip install --editable .

I strongly suggest you read https://docs.mopidy.com/en/latest/devenv/ and https://docs.mopidy.com/en/latest/extensiondev/.

Thanks a lot! Worked out fine installing.

I have though decided to use a frontend and pykka instead. I used the cookiecutter to create a frontend and it’s working. Just have to figure out if threading is the best way to handle a keypress detect loop inside on_start in frontend.py.

You missed this on IRC yesterday:

ac34:
I’m writing a frontend and I’d like to put a while loop in the on_start(self) function but when I do that the init and corelistener functions are never being called. Do I have to use threading in some way?
The while loop is for reading keystrokes. I’m gonna have callback functions for GPIO pins but until the hardware is done (RPi) i want to be able to trigger functions from keyboard as well

adamcik:
if ac34 shows up again warn against blocking on_start, there should be a separate thread for the loop or something

Thank you, now it works as intended when using threading! Now it’s only left to create a user directory for the Mopidy user for saving files. Can I somehow just create a /home/Mopidy and chown it?

Edit: seems to be the /var/lib/mopidy