[PLUGIN] Pandora Plugin 2.0

Hi @GlennBurnett

It’s hard for me to determine what is going on with your app. I don’t know what I’d need to change to get your app to work for you. When I use the Pandora plugin, the playback seems to be working as intended.

Perhaps I could readdress the flow of the plugin. If I recall correctly, when a station is chosen in the Volumio browser, the plugin selects a station and then pulls some tracks from that station, playing the first track in the group that is returned.

Maybe what needs to happen is that the tracks are loaded, but playback remains stopped / remains in the current state until a queue track is selected. Perhaps that would make more sense?

I haven’t heard very much from the developers of the project since I started this plugin a few years ago. When I started it, plugin developers were given a lot of leeway in what they could do. With the release of Volumio 3, the plugins are now curated / checked / evaluated. The Pandora plugin is in this process at the moment – I submitted it for approval maybe two weeks ago. Of course we are just finishing up the winter holidays so the approval process may take some more time.

I’m not sure what the best flow would be. I can say that Volumio handles the playback and starts the next track on its own if I recall correctly. The plugin fetches track information into the queue when a song ends until a user set limit is reached.

I’m not sure if that helps you :slight_smile:

Hi @truckershitch, I have updated to the latest version of the plugin (2.9.3) on Volumio3. Most of the time it is playing great, with the occasional stop after the first track or random stopping on a track… I am initiating the station using the Volumio Browse Rest API in Python:

S.get("http://localhost:3000/api/v1/browse?uri=" + uri)

I have also been able to call your plugin methods stop, pause, resume, next, previous etc. with the Volumio3 socket API example below:

sio.emit("callMethod", {"endpoint":"music_service/pandora","method":"pause","data": {}})

Can I use the clearAndPlayStation method below? What is the format of the data needed? The data I am using comes directly from the browse uri returned from the Volumio3 browse rest API:

jsonPlaylists = S.get("http://localhost:3000/api/v1/browse?uri=/pandora").json()

sio.emit("callMethod",{"endpoint":"music_service/pandora","method":"clearAndPlayStation","data": {"service":"pandora","type":"station","title":"INXS Radio","stationName":"INXS","albumart":"https://content-images.p-cdn.com/images/85/95/87/f6/153c48ff9e2b53f28190719a/_500W_500H.jpg","icon":"fa fa-folder-open-o","uri":"/pandora/stationToken=4058670268554901831"}})

Thanks again for all the work on the plugin and help!!

Glenn

Hi @GlennBurnett

I’m a little hazy on the details, but looking at the clearAndPlayStation() function below:

ControllerPandora.prototype.clearAndPlayStation = function (stationJSON) {
    var self = this;
    const fnName = 'clearAndPlayStation';
    const stationName = JSON.parse(stationJSON).stationName;

    self.pUtil.announceFn(fnName);

    // stationName has ' Radio' stripped from end
    const stationToken = Object.keys(self.stationData)
        .find(key => self.stationData[key].name.startsWith(stationName));

    if (typeof(stationToken) === 'undefined') {
        self.pUtil.logError(fnName, 'Station ' + stationName + ' not found!');
        return libQ.resolve();
    }
    const uri = uriPrefix + stationToken;

    return self.flushPandora()
        .then(() => self.handleBrowseUri(uri));
};

It looks like you could pass in
{"stationName": "INXS"} for the data parameter as you did there. But maybe there is a problem with scope?

The meat of that function is at the end:

const uri = uriPrefix + stationToken;
return self.flushPandora()
    .then(() => self.handleBrowseUri(uri));

uriPrefix is in common.js and according to my comment is:
'/pandora/stationToken=' I don’t have a moment to double check that but it’s there in line 11.

Perhaps prepending your stationToken with the uriPrefix and calling the API equivalent of:

  flushPandora()
    .then(() => handleBrowseUri(uriPrefix + stationToken));

would work for you?

Let me know how you’re doing!

I see something. See my comment:

// stationName has ' Radio' stripped from end

That may or may not be a problem for you. But since you have the stationToken the solution in the last post might work.

@truckershitch Thanks for the quick response. Based on your code, I have already tried a couple of the methods you described. I am doing this through Python using the Websocket API which is working great for methods that dont need parameters. I tried these again based on your suggestions:

sio.emit(“callMethod”,{“endpoint”:“music_service/pandora”,“method”:“handleBrowseUri”,“data”: {“uri”:"/pandora/stationToken=4058670268554901831"}})"
journatlctl output:

Here is the journalctl output:

Apr 19 13:13:32 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 19 13:13:32 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 19 13:13:33 volumio3dev volumio[1001]: info: CALLMETHOD: music_service pandora handleBrowseUri [object Object]
Apr 19 13:13:33 volumio3dev volumio[1001]: info: CoreCommandRouter::executeOnPlugin: pandora , handleBrowseUri
Apr 19 13:13:33 volumio3dev volumio[1001]: info: [1650399213720] ControllerPandora::handleBrowseUri
Apr 19 13:13:33 volumio3dev volumio[1001]: info: [1650399213720] ControllerPandora::checkForExpiredStations
Apr 19 13:13:33 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 19 13:13:33 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 19 13:13:34 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 19 13:13:34 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue

No errors, just no response. If I call clearAndPlayStation:

sio.emit(“callMethod”,{“endpoint”:“music_service/pandora”,“method”:“clearAndPlayStation”,“data”: {“stationName”: “INXS”}})

I get the following journalctl output:

Apr 19 13:21:06 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 19 13:21:06 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 19 13:21:06 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 19 13:21:06 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 19 13:21:06 volumio3dev volumio[1001]: info: CALLMETHOD: music_service pandora clearAndPlayStation [object Object]
Apr 19 13:21:06 volumio3dev volumio[1001]: info: CoreCommandRouter::executeOnPlugin: pandora , clearAndPlayStation
Apr 19 13:21:06 volumio3dev volumio[1001]: error: Failed callmethod call: SyntaxError: Unexpected token o in JSON at position 1
Apr 19 13:21:08 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 19 13:21:08 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 19 13:21:08 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 19 13:21:08 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue

Not sure where the “o” is coming from. From the journalctl, I am clearly getting the method, just not the correct data input.

Thanks!!

Glenn

Hmm. I wonder if the JSON for the data key has to be passed in as text?

Can you try instead:

sio.emit(
    "callMethod",
    {
        "endpoint": "music_service/pandora",
        "method": "clearAndPlayStation", 
        "data": "{'stationName': 'INXS'}"
    }
)
  • Be careful of the quotes and double-quotes in this message when cutting and pasting. sometimes they are changed by the web browser to “pretty” quotes (as seen in that word there) and they will not be interpreted correctly by your computer.

I’m not sure that will work but it’s worth a shot. It might explain why that JSON.parse() failed in the clearAddPlayTrack() function

@truckershitch same result:

Apr 20 07:18:05 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:05 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:06 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 20 07:18:06 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 20 07:18:06 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 20 07:18:08 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:08 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:08 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 20 07:18:08 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 20 07:18:08 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 20 07:18:08 volumio3dev volumio[1001]: info: CALLMETHOD: music_service pandora clearAndPlayStation {'stationName': 'INXS'}
Apr 20 07:18:08 volumio3dev volumio[1001]: info: CoreCommandRouter::executeOnPlugin: pandora , clearAndPlayStation
Apr 20 07:18:08 volumio3dev volumio[1001]: error: Failed callmethod call: SyntaxError: Unexpected token ' in JSON at position 1
Apr 20 07:18:09 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:09 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:09 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:09 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:10 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:10 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:10 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 20 07:18:10 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 20 07:18:10 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 20 07:18:12 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:12 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:12 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 20 07:18:12 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 20 07:18:12 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:14 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:16 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:16 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:16 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 20 07:18:16 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 20 07:18:16 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 20 07:18:16 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 20 07:18:16 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:16 volumio3dev volumio[1001]: info: [1650464296604] ControllerPandora::ExpireOldTracks::reaper
Apr 20 07:18:16 volumio3dev volumio[1001]: info: [1650464296604] [Pandora] ExpireOldTracks::reaper: No victims found: Expiring zero tracks.  Don't worry -- Jason will return.
Apr 20 07:18:18 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:18 volumio3dev volumio[1001]: info: CorePlayQueue::getTrack 0
Apr 20 07:18:18 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetQueue
Apr 20 07:18:18 volumio3dev volumio[1001]: info: CoreStateMachine::getQueue
Apr 20 07:18:18 volumio3dev volumio[1001]: info: CorePlayQueue::getQueue
Apr 20 07:18:19 volumio3dev volumio[1001]: info: CoreCommandRouter::volumioGetState
Apr 20 07:18:08 volumio3dev volumio[1001]: error: Failed callmethod call: SyntaxError: Unexpected token ' in JSON at position 1

Maybe an escaped double-quote? That error is different than the previous one.

sio.emit(
    "callMethod",
    {
        "endpoint": "music_service/pandora",
        "method": "clearAndPlayStation", 
        "data": "{\"stationName\": \"INXS\"}"
    }
)

@truckershitch AWESOME!!! THAT WORKED!!!

Thanks again for all your help!! Ill be working on getting the thumbs down to be more dynamic. I have a delete command (drop in garbage can) that removes tracks from the queue and playlist permanently. I can use the service state to call the thumbs down only on “delete” versus “next” for Pandora.

Best!!

Glenn

@truckershitch First - let me thank you for an outstanding plugin which has worked flawlessly for me in playing my Pandora stations. I am running v 2.9.2 on my basic pi 3b+ box with Volumio: 3.251 feeding a soundbar with a Polk sub-woofer. Since I primarily listen to internet radio and Pandora, I love the way it is working for me, especially the lack of commercial breaks (in the free edition of Pandora) :+1:t4: :+1:t4: :+1:t4:

Quick questions:

  • Are you planning at any time to add functionality to the “three dots” menu on the right? Just askin’ - no pressure :grinning:
  • Also, my OCD nature balks at not having the stations in alphabetical order. I can pick either Recent or A-Z sorting on the Pandora app and was looking for something similar. Is that at all possible here?

Thanks again!!

I had the sort functions coded but had not implemented them. I went ahead and did this yesterday. I think most will be pleased.

Version 2.10.1 is available at volumio-plugins-sources/pandora at master · truckershitch/volumio-plugins-sources · GitHub

Note that the URL / repository has changed with the new Volumio 3 release. I think this plugin will work in Volumio 2.xxx but I have not checked. I didn’t change anything except the version number from 2.9.2 to 2.9.3 for Volumio 3. As they say, YMMV.

I have not posted a PR with the devs yet, so this will not pop up on the main servers for a while.

Rock on.

Thanks for the super quick response!!
DUH!! Had to uninstall the old plugin first as I got this:
Status :Checking that the plugin is suitable for this version of Volumio The plugin can be used with this version of Volumio
Checking that the plugin is suitable for this version of Volumio The plugin can be used with this version of Volumio
Progress: 0
Status :An error occurred while installing the plugin Error: Plugin pandora already exists
An error occurred while installing the plugin Error: Plugin pandora already exists
Failed to Install Plugin

After uninstall and restart I get this:
image

Perfect!! :+1:t4: :+1:t4: :+1:t4:
My OCD personality :grinning: thanks you

@truckershitch Thanks for the update sorting options in 2.10.

I’ve notice the Pandora icon on the Volumio home screen is oversized compared to the others. Minor cosmetic issue but I thought you might want to address in a update for consistency.

You’re welcome. :slight_smile:

Thanks for that. I meant to fix that a long time ago but I forgot about it.

Done. I reduced the icon by 55%. I think that’s a good size. Version 2.10.2 pushed.

To anyone watching: I tried to use some newer Font Awesome icons but I think that Volumio uses an older version of the library, so the choices are limited. The four sort descriptions / categories are a bit wordy but I think they’re clear.

@ truckershitch - Just updated to 2.10.2 and it looks great!!

Thank you :+1:t4: :+1:t4:

@truckershitch Thanks for the icon update. Looks good in my browsers (desktop and mobile) but it still appears oversized in the official Android app. Any idea why?

Well, right after posting this I tried force stop, clearing cache AND clearing storage in the app. Now the icon is the expected size. Posting for anyone else who runs into this.

@davestlou Thanks for the fix. Those darn caches never quite flush the way you want them to. :stuck_out_tongue:

To all: I made a PR to the main Volumio plugins repo so the new version should be available on the main servers at some point. The devs are quite busy with the main project.

I updated the manual installation instructions in the Readme.md file on my fork with the new URL and paths. It’s not terribly hard to install the plugin yourself, you may get away with cutting and pasting most of it. If you see a documentation error, let me know.

Currently, the changes can be seen in the screenshots posted above:

  • The stations can be sorted (larger change)
  • Icon resized (small change)
1 Like

@davestlou Yes, I saw that on the web interface and clearing cache fixed it but I was still getting the old (large) icon with the iOS Volumio app. Uninstalling and reinstalling the app, however, fixed that too.

1 Like

Hi truckershitch,
Thanks for the work on the plug-in. I’ve been working my way through your Home Assistant integration and am struggling. I’ve got the input_select populating using the pyscript implementation of update_options. I’m running into issues triggering the playback.

If I put the socketio_send_volumio_cmd.py file in /config/bin (or just in /config) I get a permission denied error when calling the shell_command. I did try changing the permissions on the file (when it was in the /config folder). I no longer get the permission denied error, but get the following instead: 2022-05-01 13:08:58 ERROR (MainThread) [homeassistant.components.shell_command] Error running command: /config/socketio_send_volumio_cmd.py pandora clearAndPlayStation '{ "stationName": "{{ newStation }}" }', return code: 1

if I put the file in /config/pyscript and do a reload (or a reboot), the whole HA web UI crashes and the only way to recover is to connect via samba, rename the .py file to .txt , and pull the power/reboot.

Volumio 3.251 w/ Pandora 2.10.2
Home Assistant version: 2022.4.7 (supervised install, running on an odroid/Home Assistant Blue)
Pyscript version: 1.3.3

I’ve implemented everything from your repo except:

  • the files in python_scripts (these seemed to be duplicates/alternatives to the pyscript approach)
  • scripts_misc (since I’m not using Google Assistant). I also commented out script.google_sync_devices() from pyscript/update_options.py
  • the sensor from sensors_volumio.yaml (since it was commented out)
  • within the files, changed http://volumio.lan:3000 to http://volumio.local:3000

in my configuration.yaml:
shell_command:
play_volumio_pandora_station: “/config/socketio_send_volumio_cmd.py pandora clearAndPlayStation ‘{ “stationName”: “{{ newStation }}” }’”

Any help/guidance would be appreciated.

Rich