Google Music in HA -- Using AppDaemon

I’m sure most of you clicking on this are familiar with the great work @Danielhiversen has done creating Google Music in HA. While this (as of today) continues to work with minor tweaks here and there the project itself is no longer being developed. With current changes happening in HA I fear it’s only a matter of time before it stops working all together.

@ajfriesen Created a feature request for an official component Please go vote!.


Update 06/01/19:

Please now consider using gmusic as a media player instead



My intention here is NOT creating an “official component” although that is something I hope to contribute toward in the future. For now I have found AppDaemon to be an easier approach to start learning python and the unofficial Google Music api. Please keep in mind, I am not a programmer and just starting out, I have only learned some basics of AppDaemon and Python. Using the original gmusic in HA code as a reference I’ve managed this, not perfect, but useable alternative to the original Google Music in HA.

I’ve also slightly furthered functionality by adding a few things I greatly wished for in the original

  • Listen to “I’m Feeling Lucky” and other stations saved in your GM library
  • Sync your playlists and stations from GM library without restarting HA


This app requires installing gmusicapi

If your running appdaemon in a virtualenv

Click Here

This is not horrible but does require using the terminal to install gmusicapi and (optionally) create the oauth-credentials file. Here I assume both Home Assistant and AppDaemon are installed and running in separate virtualenv on the same host. I have installed gmusicapi inside the same virtualenv as AppDaemon. Your paths maybe different but here’s how I installed gmusicapi and got my oauth-file. In most cases you will only need to create the oauth once.

Install gmusicapi

In my setup, HomeAssistant and AppDaemon both run by user hass so I’ll start by changing to that user, activating the appdaemon virtualenv and installing gmusicapi

su - hass
source /srv/appdaemon/bin/activate
pip3 install --upgrade gmusicapi

Now before exiting the virtualenv we’ll use gmusicapi to create the oauth file.

Creating oauth credentials for gmusicapi

Again, still inside the appdaemon virtualenv, begin by starting an interactive python shell

 python 

Now from the python shell we can create the oauth file in several simple steps. I’ve named my oauth file GoogleMusic.oauth but you can pick any name. I think it’s easiest to save this file in the appdaemon config dir. For example: /home/hass/appdaemon/conf/GoogleMusic.oauth but really it can be saved anywhere accessible by appdaemon.

from gmusicapi import Mobileclient
mc = Mobileclient()
mc.perform_oauth(storage_filepath="/home/hass/appdaemon/conf/GoogleMusic.oauth", open_browser=False)

Follow the on screen instructions and you will create your oauth file.

Basically the last command will give you a link. Go to the url and login with the (google) account you want to use with google music. This will intern give a long app password to paste back in the terminal. That’s it for getting the oauth file!

Testing oauth login

Next we’ll quickly test the new log in. If you don’t know your device_id don’t worry. Just use something like 000 . This will fail to connect to Google Music. However if your login is valid, this will return a list of valid device_id s. Using one from the list, test the login again

mc.oauth_login(device_id='21150e2000000456', oauth_credentials='/home/hass/appdaemon/conf/GoogleMusic.oauth', locale='en_US')

This must return True in order for oauth login to work correctly.

Finish up in the terminal

Exit the python shell and deactivate the appdaemon virtualenv

exit()
deactivate
Click Here to see how that looked in my terminal
### url = https://unofficial-google-music-api.readthedocs.io/en/latest/reference/mobileclient.html#mobileclient-interface

### REQUIRES: gmusicapi
### Since it's for appdaemon: Install this in the appdaemon virtualenv
$ su - hass
$ source /srv/appdaemon/bin/activate
$ pip3 install --upgrade gmusicapi

$ python
------------------------------------------------------------------------------------------
Python 3.6.7 (default, Mar 30 2019, 01:09:45) 
[GCC 4.2.1 Compatible FreeBSD Clang 6.0.0 (tags/RELEASE_600/final 326565)] on freebsd11
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> from gmusicapi import Mobileclient
>>> mc = Mobileclient()
>>> mc.perform_oauth(storage_filepath="/home/hass/appdaemon/conf/GoogleMusic.oauth", open_browser=False)

Visit the following url:
 https://accounts.google.SOME-RANDOMLY-LONG-URL
Follow the prompts, then paste the auth code here and hit enter:

### To Get A Valid Device ID try to log in without one:
>>> mc.oauth_login(device_id='000', oauth_credentials='/home/hass/appdaemon/conf/gmusic.cred', locale='en_US')

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/srv/appdaemon/lib/python3.6/site-packages/gmusicapi/clients/mobileclient.py", line 183, in oauth_login
    return self._login(session_login, device_id, locale)
  File "/srv/appdaemon/lib/python3.6/site-packages/gmusicapi/clients/mobileclient.py", line 143, in _login
    self.android_id = self._validate_device_id(device_id, is_mac=is_mac)
  File "/srv/appdaemon/lib/python3.6/site-packages/gmusicapi/clients/mobileclient.py", line 80, in _validate_device_id
    raise InvalidDeviceId('Invalid device_id %s.' % device_id, device_ids)
gmusicapi.exceptions.InvalidDeviceId: Invalid device_id 000.Your valid device IDs are:
* 11150e2000000123
* 21150e2000000456
* 31150e2000000789
------------------------------------------------------------------------------------------

### Test your login
>>> mc.oauth_login(device_id='21150e2000000456', oauth_credentials='/home/hass/appdaemon/conf/gmusic.cred', locale='en_US')
True
>>>
>>> mc.logout()
True
>>>
>>> exit()

$
$ deactivate

### Make file read-only for hass
$ chmod 400 /home/hass/appdaemon/conf/GoogleMusic.oauth


If your using the hassio addon

Click Here

Well this does work but seriously consider using gmusic as a media player instead. Don’t even think about this on a PI device. Maybe if you have a decent Intel NUC but be warned the issue is during installation of gmusicapi, building wheel for lxml can take as long as 10 minutes to install using an older i7. And this delay is going to happen on every reboot.

Add the following to your appdaemon config. It can take several minutes for these packages to be installed during appdaemon startup.

{
  "disable_auto_token": false,
  "system_packages": [
    "build-base",
    "libxslt-dev",
    "libxml2-dev",
    "gcc"
  ],
  "python_packages": [
    "setuptools",
    "gmusicapi",
    "lxml"
  ]
}


Add entities to Home Assistant.

The original GM in HA is built on a custom switch component. This app simply relies mainly on the input_boolean and input_select entities which can be easily added and configured using a Home Assistant package . I name this gmaac_package.yaml but the name does not matter, it can be any_name.yaml

You will need to add your own media players under gmaac_player . For example to add media_player.bedroom_stereo you would add bedroom_stereo. Sorry you still can not use friendly names here.

homeassistant/packages/gmaac_package.yaml
https://github.com/tprelog/GoogleMusic_HomeAssistant/blob/master/homeassistant/packages/gmaac_package.yaml


Adding GMAAC (Google Music All Access Control) to AppDaemon

Create a directory inside your appdaemon apps called gmaac that will contain two files
gmaac.yaml and gmaac.py

gmaac.yaml contains the configuration . You will need to edit the device_id and set the desired login_type your using for the gmusicapi.

It would be preferred to use the oauth login. Set oauth_credentials to the location of your GoogleMusic.oauth

The legacy login is available if you are unable to create GoogleMusic.oauth. With the legacy login you should be able to use the same user and password that you would use for the original GM custom switch.

appdaemon/apps/gmaac/gmaac.yaml
https://github.com/tprelog/GoogleMusic_HomeAssistant/blob/master/homeassistant/appdaemon/apps/gmaac/gmaac.yaml

appdaemon/apps/gmaac/gmaac.py
https://github.com/tprelog/GoogleMusic_HomeAssistant/blob/master/homeassistant/appdaemon/apps/gmaac/gmaac.py

3 Likes

Would ove to give it a shot!

Thank you very much. If I get time in the next days I will definitely give this a try!
Only difference would be that I am running hassio.

Took a few small steps forward:

  • I renamed things so this can be used for testing while still using the original GM in HA. They can not be playing at the same time, but they can exist together

  • The login (connect) now works like I wanted. So it’s activated by default which logs in to gmusicapi and will update the playlists on startup just like the original GM in HA. Really no need to interact with this but it’s there if you need to logout (of gmusic) for some reason.

  • Playlists are updated upon successful login as the original did but also sync playlist can be used if you change/add your playlists on GM.

I’ve tried to add song information to the media_player attributes using set_state. This reflects correctly on the states page in HA but only the song title shows up in the default media player


image

I was glad to see mini-media-player at least display the artist and title


I had better luck in hadashboard (which is my main use case for this app) and have been pretty happy with early testing. This configuration is not included here because at this point it’s single purpose was to see if I could even get song information and artwork to work.

image

Updated here


I know I still have a lot to learn. Even where this does work I’m sure there is room for improvement or better ways to do things. I would welcome any advice and constructive criticism but again please remember I am very new to this (python and appdaemon)

Got the stations working! I first tried all stations but that returned over 150 stations! Thought that might be a bit much so to narrow the list, I put a check in so only stations that have been added to your music library will populate the input select.

Another input select can switch the playback source- Station or Playlist

image

I’m going to try and add podcasts in the future. I think I’ll at least add something for the Home Assistant Podcast for sure!

Finaly came around to install it - Sadly I Couldnt get it running with Hassio.
maybe some other Hassio user can get it running - So far I got until now

{
  "disable_auto_token": false,
  "system_packages": [
    "build-base",
    "libxml2",
    "libxml2-dev",
    "gcc"
  ],
  "python_packages": [
    "setuptools",
    "gmusicapi",
    "lxml"
  ]
}
/local/include/python3.7m -c src/lxml/etree.c -o build/temp.linux-x86_64-3.7/src/lxml/etree.o -w
    In file included from src/lxml/etree.c:687:
    src/lxml/includes/etree_defs.h:14:10: fatal error: libxml/xmlversion.h: No such file or directory
     #include "libxml/xmlversion.h"
              ^~~~~~~~~~~~~~~~~~~~~
    compilation terminated.
    Compile failed: command 'gcc' failed with exit status 1
    cc -I/usr/include/libxml2 -c /tmp/xmlXPathInit0bv9_la7.c -o tmp/xmlXPathInit0bv9_la7.o
    /tmp/xmlXPathInit0bv9_la7.c:2:1: warning: return type defaults to 'int' [-Wimplicit-int]
     main (int argc, char **argv) {
     ^~~~
    cc tmp/xmlXPathInit0bv9_la7.o -lxml2 -o a.out
    error: command 'gcc' failed with exit status 1
    
    ----------------------------------------
Command "/usr/local/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-6b8mvrv3/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-avkdovql/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-6b8mvrv3/lxml/
[14:32:53] FATAL: Failed installing package gmusicapi
[cont-init.d] appdaemon.sh: exited 1.
[cont-finish.d] executing container finish scripts...
[cont-finish.d] 99-message.sh: executing... 
-----------------------------------------------------------
                Oops! Something went wrong.

thanks to Frenck who helped me understanding a little the dependency. as it looks like libxml2-dev making trouble T_T

@Underknowledge

I’m running HA and AD on FreeNAS so these package names are likely to be different but I needed to install libxml2 and libxslt before I could use the gmusicapi (This was also true when I was using the original GM custom switch)

I did not mention that here thinking it was related to FreeNAS only.

Maybe those package names could provide you a clue if your maybe missing a dependency. This is just a guess though

Edit:
I also say that I’ve still been playing around with the original GM switch. I have not made any headway towards creating a new custom component for GM but I have (I think) learned enough so far that I will be able to add the additional functionality created here back into the original custom component. I was also able to work around the Config Warning so I think we’ll be able to keep that alive a bit longer.

1 Like

Would be nice as F.
added libxslt but no real change

    error: command 'gcc' failed with exit status 1
    
    ----------------------------------------
Command "/usr/local/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-6gx5qedl/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-65afzpbe/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-6gx5qedl/lxml/
[16:19:42] FATAL: Failed installing package gmusicapi
[cont-init.d] appdaemon.sh: exited 1.
[cont-finish.d] executing container finish scripts...
[cont-finish.d] 99-message.sh: executing... 

Probably a Alpinelinux problem

I’m gonna have to start using hass.io just because everybody does. I know I could help figure this out if I actually used it enough to understand more.

This has to install somehow because your using the original GM switch. So gmusicapi will install somehow because it installs in HA.

I’ll post my workaround for the Config Warning by this weekend.

@Underknowledge

Sorry I may have said that a bit too soon. I upgraded to HA 92.0 this afternoon and the original GM switch is just causing HA to hang about halfway through startup. It’s not throwing any errors but still HA won’t start even with what I thought was gonna be a workaround.

@Underknowledge

This works

{
  "disable_auto_token": false,
  "system_packages": [
    "build-base",
    "libxslt-dev",
    "libxml2-dev",
    "gcc"
  ],
  "python_packages": [
    "setuptools",
    "gmusicapi",
    "lxml"
  ]
}

No errors but I’m still trying to figure out how to create the oauth file.

Edit:
I set up hass.io in a virtual machine and installed gmusicapi to the appdaemon addon using the above config. I copied my configuration for the appdaemon google music app including my existing oauth file over to hass.io and everything does work. I just have no idea how you could create the oauth file using hass.io. Is there a way to get to a terminal inside the appdaemon addon?

Edit 05-02

These file have been moved to github.
The first post has been updated and now includes links to the necessary files

Update 06/01/19:

Please now consider using gmusic as a media player instead

Mhmm… Still cant start it - complaining bout select_station

Google Music using class GMAAC from module gmaac
2019-04-26 13:21:53.880844 WARNING AppDaemon: ------------------------------------------------------------
2019-04-26 13:21:53.881174 WARNING AppDaemon: Unexpected error running initialize() for Google Music
2019-04-26 13:21:53.881503 WARNING AppDaemon: ------------------------------------------------------------
2019-04-26 13:21:53.885127 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 1581, in init_object
    init()
  File "/config/appdaemon/apps/gmaac.py", line 16, in initialize
    self.select_station = self.args["select_station"]
KeyError: 'select_station'

2019-04-26 13:21:53.885423 WARNING AppDaemon: ------------------------------------------------------------
2019-04-26 13:21:53.887037 INFO AppDaemon: App initialization complete

when i add select_station: input_select.gmaac_station to the apps.yaml I get:

2019-04-26 13:03:34.582651 INFO AppDaemon: Initializing app Google Music using class GMAAC from module gmaac
2019-04-26 13:03:34.586303 WARNING AppDaemon: ------------------------------------------------------------
2019-04-26 13:03:34.586635 WARNING AppDaemon: Unexpected error running initialize() for Google Music
2019-04-26 13:03:34.586875 WARNING AppDaemon: ------------------------------------------------------------
2019-04-26 13:03:34.590282 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 1581, in init_object
    init()
  File "/config/appdaemon/apps/gmaac.py", line 18, in initialize
    self.select_playmode = self.args["select_mode"]
KeyError: 'select_mode'

2019-04-26 13:03:34.590562 WARNING AppDaemon: -----------------------------------------------------------2019-04-26 13:03:34.591977 INFO AppDaemon: App initialization complete

could use the docker commandline.
But I just created a venv on my PC and copyed the file over

To the custom component. you just forgot to add a __init__.py ? :rofl: still hoping wheel for lxml takes forever
https://developers.home-assistant.io/blog/2019/04/12/new-integration-structure.html

Ugh… I copied the wrong apps.yaml (I really need to get this in github) but I have made the correction to my post. Please try again with the now (hopefully) corrected files show above your post

Yea I have that already. No luck :frowning:

aaaahhh… close

 --------------------------------------------
2019-04-27 08:34:59.492723 INFO Google Music: Loading [34] Tracks From: -a5 instumental backgr
2019-04-27 08:34:59.494840 INFO Google Music: --------------------------------------------
2019-04-27 08:34:59.495178 WARNING AppDaemon: ------------------------------------------------------------
2019-04-27 08:34:59.495530 WARNING AppDaemon: Unexpected error in worker for App Google Music:
2019-04-27 08:34:59.495919 WARNING AppDaemon: Worker Ags: {'name': 'Google Music', 'id': UUID('092f62db-297d-4bec-a220-3e3e59f247f5'), 'type': 'attr', 'function': <bound method GMAAC.get_tracks of <gmaac.GMAAC object at 0x7f99ab7201d0>>, 'attribute': 'state', 'entity': 'input_boolean.gmaac_load_pl', 'new_state': 'on', 'old_state': 'off', 'kwargs': {'new': 'on', 'handle': UUID('a1e14525-x-79ad71714541')}}
2019-04-27 08:34:59.496220 WARNING AppDaemon: ------------------------------------------------------------
2019-04-27 08:34:59.496919 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 595, in worker
    self.sanitize_state_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/gmaac.py", line 196, in get_tracks
    self.load_playlist(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac.py", line 216, in load_playlist
    self.get_track(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac.py", line 258, in get_track
    self._song = _track['track']
KeyError: 'track'

2019-04-27 08:34:59.497181 WARNING AppDaemon: ------------------------------------------------------------
2019-04-27 08:40:38.804446 WARNING AppDaemon: Excessive time spent in utility loop: 1105.0ms
2019-04-27 10:47:19.522640 INFO Google Music: --------------------------------------------
2019-04-27 10:47:19.524576 INFO Google Music: Loading [34] Tracks From: -a5 instumental backgr
2019-04-27 10:47:19.526401 INFO Google Music: --------------------------------------------
2019-04-27 10:47:19.526745 WARNING AppDaemon: ------------------------------------------------------------
2019-04-27 10:47:19.527067 WARNING AppDaemon: Unexpected error in worker for App Google Music:
2019-04-27 10:47:19.527510 WARNING AppDaemon: Worker Ags: {'name': 'Google Music', 'id': UUID('092f62db-297d-4bec-a220-3e3e59f247f5'), 'type': 'attr', 'function': <bound method GMAAC.get_tracks of <gmaac.GMAAC object at 0x7f99ab7201d0>>, 'attribute': 'state', 'entity': 'input_boolean.gmaac_load_pl', 'new_state': 'on', 'old_state': 'off', 'kwargs': {'new': 'on', 'handle': UUID('a1e14525-x-79ad71714541')}}
2019-04-27 10:47:19.527759 WARNING AppDaemon: ------------------------------------------------------------
2019-04-27 10:47:19.528446 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 595, in worker
    self.sanitize_state_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/gmaac.py", line 196, in get_tracks
    self.load_playlist(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac.py", line 216, in load_playlist
    self.get_track(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac.py", line 258, in get_track
    self._song = _track['track']
KeyError: 'track'

2019-04-27 10:47:19.528705 WARNING AppDaemon: ------------------------------------------------------------

Dang almost! Im traveling for work till Tuesday. Ill try to look at this when I get my hotel but might be slow for the next few days

@Underknowledge

Ok let’s try this one more time. I did just edit my post and copied directly from my working gmaac.py to this thread. Can you try one more time?

If you still get an error can you please try a few other things like maybe a different playlist. Does anything work from the stations? How about `I’m feeling lucky?

If none of your playlist will work can you make a new playlist containing one song, Then inside gmaac.py around lines 211 and 212 you will the following.

    self.log("Loading [{}] Tracks From: {}".format(len(self._tracks), self._playlist_id))
    # self.log(self._tracks)

remove the comment (#) so it now looks like this and save the file

    self.log("Loading [{}] Tracks From: {}".format(len(self._tracks), self._playlist_id))
    self.log(self._tracks)

Finally try to play the playlist with one song and kindly post the log when it errors.

I’m not sure what Im missing. Thanks for putting up with the head-aches to help me get this working for everyone!

Lol - I think you can imagine that it is also for me a big deal when GMusic is finnaly back to a working state :rofl:

I dont have the ["I'm Feeling Lucky"] in Playlists
(only when the script did not had the time to overwrite the playlists)
Loading process:

2019-04-28 09:41:43.805894 INFO Google Music: --------------------------------------------
2019-04-28 09:41:43.806295 INFO Google Music: ['15.12 will mal wieder', '1.15 1', 'on the Spotlight', '00-kontra_k-aus_dem_schatten_ins_licht-de-2015-noir', '.new 0114', '0- Auto', 'Likes', 'ipod', '-a5 Weich', '-. mhmm 1', '.--.-. plus neu', 'KENNENLERNRUNDEN', '???', '.-. a mal wieder?', '-- a ip bo', 'JUL 15 HART', 'Jun 15', 'All', 'New Playlist 1', '.square bo', 'Rhyminsimon', 'Humorvoll', 'Oldscool', 'Nachdenklich', 'Raketig', 'Genetikk', 'Jul15 Kein Text Herlich', 'Spoken View Rundschau', '2016 Zahnarzt', 'Musikalische Wahrheit', '.- Aaactuall', 'Mach n Klingel Ton draus', 'Run', 'Soul', 'November?', 'August 16 goody', '1! WTF!', "000 VA's", 'September 2016 nice', 'Runde Sache', '111 ��ndern', 'Kolle', 'Downbeat', '000 eine w��hrende playlist', 'Faustkampf', 'Neugierde', 'A ip bo 1', 'Klingelton', 'SPORT', '����laufen', '01. Offline', 'ZM', 'Kostenlos', 'Morgen', 'Ich weine gleich', '-a5 instumental backgr', '.pls']
2019-04-28 09:41:43.808413 INFO Google Music: 1: 15.12 will mal wieder
2019-04-28 09:41:43.810482 INFO Google Music: 2: 1.15 1
2019-04-28 09:41:43.812743 INFO Google Music: 3: on the Spotlight
...
..
2019-04-28 09:41:43.910846 INFO Google Music: 50: ����laufen
2019-04-28 09:41:43.912910 INFO Google Music: 51: 01. Offline
2019-04-28 09:41:43.914912 INFO Google Music: 52: ZM
2019-04-28 09:41:43.916968 INFO Google Music: 53: Kostenlos
2019-04-28 09:41:43.919101 INFO Google Music: 54: Morgen
2019-04-28 09:41:43.921164 INFO Google Music: 55: Ich weine gleich
2019-04-28 09:41:43.923169 INFO Google Music: 56: -a5 instumental backgr
2019-04-28 09:41:43.925219 INFO Google Music: 57: .pls
2019-04-28 09:41:43.927231 INFO Google Music: --------------------------------------------
2019-04-28 09:41:44.341947 INFO Google Music: --------------------------------------------
2019-04-28 09:41:44.342361 INFO Google Music: ["I'm Feeling Lucky"]
2019-04-28 09:41:44.344943 INFO Google Music: --------------------------------------------
2019-04-28 09:41:49.754232 INFO Google Music: Powered ON -- Connected: media_player.mini
2019-04-28 09:41:51.207083 INFO Google Music: --------------------------------------------
2019-04-28 09:19:54.445010 INFO Google Music: 56: -a5 instumental backgr
2019-04-28 09:19:54.446952 INFO Google Music: 57: .pls
2019-04-28 09:19:54.448864 INFO Google Music: --------------------------------------------
2019-04-28 09:19:54.879681 INFO Google Music: --------------------------------------------
2019-04-28 09:19:54.880043 INFO Google Music: ["I'm Feeling Lucky"]
2019-04-28 09:19:54.882243 INFO Google Music: --------------------------------------------
2019-04-28 09:20:09.679721 INFO Google Music: Powered ON -- Connected: media_player.mini
2019-04-28 09:20:09.681708 INFO Google Music: --------------------------------------------
2019-04-28 09:20:09.685017 INFO Google Music: Loading [20] Tracks From: .--.-. plus neu
2019-04-28 09:20:09.688487 INFO Google Music: --------------------------------------------
2019-04-28 09:20:09.688968 WARNING AppDaemon: ------------------------------------------------------------
2019-04-28 09:20:09.689399 WARNING AppDaemon: Unexpected error in worker for App Google Music:
2019-04-28 09:20:09.690013 WARNING AppDaemon: Worker Ags: {'name': 'Google Music', 'id': UUID('f6b6bc6f-x-8e67a104a468'), 'type': 'attr', 'function': <bound method GMAAC.get_tracks of <gmaac.GMAAC object at 0x7ff872830470>>, 'attribute': 'state', 'entity': 'input_boolean.gmaac_load_pl', 'new_state': 'on', 'old_state': 'off', 'kwargs': {'new': 'on', 'handle': UUID('f076079a-x-beb43be2ac5f')}}
2019-04-28 09:20:09.690365 WARNING AppDaemon: ------------------------------------------------------------
2019-04-28 09:20:09.691156 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 595, in worker
    self.sanitize_state_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/gmaac.py", line 195, in get_tracks
    self.load_playlist(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac.py", line 215, in load_playlist
    self.get_track(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac.py", line 257, in get_track
    self._song = _track['track']  ## use with playlist
KeyError: 'track'

2019-04-28 09:20:09.691606 WARNING AppDaemon: ------------------------------------------------------------

Now with a playlist containing one song:


2019-04-28 09:41:43.923169 INFO Google Music: 56: -a5 instumental backgr
2019-04-28 09:41:43.925219 INFO Google Music: 57: .pls
2019-04-28 09:41:43.927231 INFO Google Music: --------------------------------------------
2019-04-28 09:41:44.341947 INFO Google Music: --------------------------------------------
2019-04-28 09:41:44.342361 INFO Google Music: ["I'm Feeling Lucky"]
2019-04-28 09:41:44.344943 INFO Google Music: --------------------------------------------
2019-04-28 09:41:49.754232 INFO Google Music: Powered ON -- Connected: media_player.mini
2019-04-28 09:41:51.207083 INFO Google Music: --------------------------------------------
2019-04-28 09:41:51.209348 INFO Google Music: Loading [1] Tracks From: Oldscool
2019-04-28 09:41:51.209720 INFO Google Music: [{'kind': 'sj#playlistEntry', 'id': 'dc125a35-d061-316e-9f9d-b42e58c91668', 'clientId': '5c7b09e6-e4d7-4609-82b2-4f7236e7cd84', 'playlistId': '41408b42-ea61-42fc-ab67-347ec4c35e77', 'absolutePosition': '01729382256910270462', 'trackId': '5caef26a-fbd8-3c87-a05b-588473897b10', 'creationTimestamp': '1472161720730418', 'lastModifiedTimestamp': '1472161720730418', 'deleted': False, 'source': '1'}]
2019-04-28 09:41:51.211632 INFO Google Music: --------------------------------------------
2019-04-28 09:41:51.211915 WARNING AppDaemon: ------------------------------------------------------------
2019-04-28 09:41:51.212179 WARNING AppDaemon: Unexpected error in worker for App Google Music:
2019-04-28 09:41:51.212502 WARNING AppDaemon: Worker Ags: {'name': 'Google Music', 'id': UUID('e06291e8-d3a1-41db-b72b-49536f0ec545'), 'type': 'attr', 'function': <bound method GMAAC.get_tracks of <gmaac.GMAAC object at 0x7f8afea0deb8>>, 'attribute': 'state', 'entity': 'input_boolean.gmaac_load_pl', 'new_state': 'on', 'old_state': 'off', 'kwargs': {'new': 'on', 'handle': UUID('9d3975bf-b77d-48f6-8b29-14b645b3428a')}}
2019-04-28 09:41:51.212735 WARNING AppDaemon: ------------------------------------------------------------
2019-04-28 09:41:51.213322 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 595, in worker
    self.sanitize_state_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/gmaac.py", line 195, in get_tracks
    self.load_playlist(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac.py", line 215, in load_playlist
    self.get_track(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac.py", line 257, in get_track
    self._song = _track['track'] ## TESTDOIHAVETORESTART??
KeyError: 'track'

2019-04-28 09:41:51.213640 WARNING AppDaemon: ------------------------------------------------------------

What makes my live easyer - In good old HA manner I always restarted AppDeamon - Not needed as I see :stuck_out_tongue:

@Underknowledge
First most time time saving tip… you do not need to keep restarting appdaemon. Each time you save the files in appdaemon apps it will automatically be detected and appdaemon will reload the app

Now when appdaemon starts or initializes Google Music (before you try to play any songs) Your appdaemon log (related to this Google Music ) should look similar. Obviously your playlist and station names would be different. I see some of this in your logs already posted but please confirm based on my example shown below you should see two groups of list.

  • The first list (starting with numbers 1-7) are my playlists saved in Google Music ( this is what the original GM would fetch and play)
  • The second list (starting with 72 and skipping numbers) are stations I have added to my Google Music library
2019-04-28 08:00:21.185610 INFO AppDaemon: Initializing app Google Music using class GMAAC from module gmaac
2019-04-28 08:00:21.207669 INFO AppDaemon: App initialization complete
2019-04-28 08:00:23.494002 INFO Google Music: --------------------------------------------
2019-04-28 08:00:23.494116 INFO Google Music: ['Random', 'Passenger (60)', 'Shinedown (70)', 'One Song', '3 Songs', 'Shinedown Radio (25)', 'Passenger Mix (25)']
2019-04-28 08:00:23.494670 INFO Google Music: 1: Random
2019-04-28 08:00:23.495194 INFO Google Music: 2: Passenger (60)
2019-04-28 08:00:23.495769 INFO Google Music: 3: Shinedown (70)
2019-04-28 08:00:23.496301 INFO Google Music: 4: One Song
2019-04-28 08:00:23.496890 INFO Google Music: 5: 3 Songs
2019-04-28 08:00:23.497406 INFO Google Music: 6: Shinedown Radio (25)
2019-04-28 08:00:23.497917 INFO Google Music: 7: Passenger Mix (25)
2019-04-28 08:00:23.498554 INFO Google Music: --------------------------------------------
2019-04-28 08:00:24.144779 INFO Google Music: --------------------------------------------
2019-04-28 08:00:24.144896 INFO Google Music: ["I'm Feeling Lucky", 'Feel-Good Alternative', 'New Release Radio', "Pop-Rock Hits of the '00s", "Feelin' Good in the '90s", 'Arena Rock Driving', 'The Smashing Pumpkins', "'90s Alternative Rock", 'Tool', 'Dave Matthews Band', 'Kings Of Leon', 'Disturbed', 'Just Give Me a Reason (feat. Nate Ruess)', 'Nine Inch Nails', 'Pearl Jam', 'Modern Rock Uprising']
2019-04-28 08:00:24.145499 INFO Google Music: 72: Feel-Good Alternative
2019-04-28 08:00:24.145966 INFO Google Music: 99: New Release Radio
2019-04-28 08:00:24.146491 INFO Google Music: 109: Pop-Rock Hits of the '00s
2019-04-28 08:00:24.146964 INFO Google Music: 111: Feelin' Good in the '90s
2019-04-28 08:00:24.147494 INFO Google Music: 131: Arena Rock Driving
2019-04-28 08:00:24.147974 INFO Google Music: 137: The Smashing Pumpkins
2019-04-28 08:00:24.148487 INFO Google Music: 156: '90s Alternative Rock
2019-04-28 08:00:24.148948 INFO Google Music: 157: Tool
2019-04-28 08:00:24.149412 INFO Google Music: 158: Dave Matthews Band
2019-04-28 08:00:24.149876 INFO Google Music: 159: Kings Of Leon
2019-04-28 08:00:24.150321 INFO Google Music: 162: Disturbed
2019-04-28 08:00:24.150924 INFO Google Music: 164: Just Give Me a Reason (feat. Nate Ruess)
2019-04-28 08:00:24.151512 INFO Google Music: 165: Nine Inch Nails
2019-04-28 08:00:24.151955 INFO Google Music: 166: Pearl Jam
2019-04-28 08:00:24.152487 INFO Google Music: 168: Modern Rock Uprising
2019-04-28 08:00:24.152947 INFO Google Music: --------------------------------------------

Aside from the names does your appdaemon log look similar after initializing Google Music?

That’s a clue!

I moved I'm feeling Lucky to a separate input_select that should only contain any stations you may have saved to you GM library. If you still see I'm Feeling Luck under Playlists and not in a separate input_select called Stations then you may still be using an older version of a file.

There is a group defined at the bottom of the package.yaml file but that may only appear in Home Assistant if you switch back to the old states UI

Lovelace config for this entities card is shown below:

type: entities
entities:
  - input_boolean.gmaac_connect
  - input_boolean.gmaac_sync
  - input_select.gmaac_player
  - input_boolean.gmaac_power
  - input_select.gmaac_mode
  - input_select.gmaac_playlist
  - input_select.gmaac_station
  - input_boolean.gmaac_load_pl
title: Google Music Control
show_header_toggle: false

Unfortunately I forgot to fix my VPN before I left so I can not do much from the road :frowning: . They keep me pretty busy when I’m traveling anyways but I’ll at least try to these file up to GitHub.

In the mean time please try replacing all 3 files with the ones (updated again) in this post.

Thanks again

@Underknowledge.
I figured out how to recreate the error.

Can you confirm if your playlist contains music not usually found on google Music but instead contains music you have uploaded?

A little more information for those following along… From the gmusicapi docs

In my case for example the band “Tool” is normally not available on GM. I have uploaded my “Tool” albums to GM and created a playlist containing only one “Tool” song.

When I try to play this “Tool” playlist I get the same error as you!

2019-04-28 09:58:06.697837 INFO Google Music: Loading [1] Tracks From: Tool
2019-04-28 09:58:06.698092 INFO Google Music: [{'kind': 'sj#playlistEntry', 'id': '0891b922-c089-34ab-a6b6-1e598d10007e', 'clientId': 'd5cd3f95-8eea-4df7-825f-010ad6dd8a51', 'playlistId': 'e9967c01-d744-4996-8296-bc395d56ecae', 'absolutePosition': '01729382256910270462', 'trackId': '6d8a3c8d-5337-33d8-a094-84775f79219b', 'creationTimestamp': '1556459871492658', 'lastModifiedTimestamp': '1556459871492658', 'deleted': False, 'source': '1'}]
2019-04-28 09:58:06.699745 INFO Google Music: --------------------------------------------
<string>:2: GmusicapiWarning: login is deprecated and may break unexpectedly; prefer Mobileclient.oauth_login
2019-04-28 09:58:06.700247 WARNING AppDaemon: ------------------------------------------------------------
2019-04-28 09:58:06.700750 WARNING AppDaemon: Unexpected error in worker for App Google Music:
2019-04-28 09:58:06.701197 WARNING AppDaemon: Worker Ags: {'name': 'Google Music', 'id': UUID('aab0723a-d5c8-4559-9480-eb18c18af818'), 'type': 'attr', 'function': <bound method GMAAC.get_tracks of <gmaac.GMAAC object at 0x7f6d783505c0>>, 'attribute': 'state', 'entity': 'input_boolean.gmaac_load_pl', 'new_state': 'on', 'old_state': 'off', 'kwargs': {'new': 'on', 'handle': UUID('6b8b918e-98c1-4b22-a335-f44b06d5c8eb')}}
2019-04-28 09:58:06.701699 WARNING AppDaemon: ------------------------------------------------------------
2019-04-28 09:58:06.702441 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 595, in worker
    self.sanitize_state_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/gmaac/gmaac.py", line 195, in get_tracks
    self.load_playlist(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac/gmaac.py", line 215, in load_playlist
    self.get_track(entity=None,attribute=None,old=None,new=None,kwargs=None)
  File "/config/appdaemon/apps/gmaac/gmaac.py", line 257, in get_track
    self._song = _track['track']  ## use with playlist
KeyError: 'track'
2019-04-28 09:58:06.702680 WARNING AppDaemon: ------------------------------------------------------------

However with another playlist containing music that is hosted GM

2019-04-28 10:16:19.805687 INFO Google Music: Loading [1] Tracks From: One Song
2019-04-28 10:16:19.806019 INFO Google Music: [{'kind': 'sj#playlistEntry', 'id': 'bf2d4f28-1c89-379a-ba32-aa784632f467', 'clientId': 'a64992e3-3387-4e79-ac73-d9dee23b5438', 'playlistId': '23a40c12-97ed-46b5-bf51-cc61f58358f6', 'absolutePosition': '01729382256910270462', 'trackId': 'Tqsoq377cnvfjnbrdnridakjxgq', 'creationTimestamp': '1543119180676684', 'lastModifiedTimestamp': '1543119180676684', 'deleted': False, 'source': '2', 'track': {'kind': 'sj#track', 'title': 'One of Us', 'artist': 'New Politics', 'composer': '', 'album': 'Lost in Translation', 'albumArtist': 'New Politics', 'year': 2017, 'trackNumber': 2, 'genre': 'Alternative/Indie', 'durationMillis': '260000', 'albumArtRef': [{'kind': 'sj#imageRef', 'url': 'http://lh3.googleusercontent.com/P7wa-b9xDhWQBlXrxpgDomDf4lLZ0gaRcovKbYWg2OIk06hiCKeiDqFnhs3Rk9l8KhdKHrYK3DM', 'aspectRatio': '1', 'autogen': False}], 'artistArtRef': [{'kind': 'sj#imageRef', 'url': 'http://lh3.googleusercontent.com/TLsxhjONnqaf1QIZXqrsIIoOPgq8WWGbxDU_YgkIlrFfKshks-T2NsijtMGv_sXaZXtgQGUgJw', 'aspectRatio': '2', 'autogen': False}, {'kind': 'sj#imageRef', 'url': 'http://lh3.googleusercontent.com/ExT25G45r-mOFsMgDCDfQ57HD8jKZvwFPe7aoGM07kfAuneflgvg47WoROR7PRR16NyTUJPKpbA', 'aspectRatio': '1', 'autogen': False}], 'playCount': 5, 'discNumber': 1, 'estimatedSize': '10406175', 'trackType': '7', 'storeId': 'Tqsoq377cnvfjnbrdnridakjxgq', 'albumId': 'B7t6flbjv53yn4fvkhfm2mwbj7q', 'artistId': ['Apeewgmoqootat5upa6zq4wgjla'], 'nid': 'qsoq377cnvfjnbrdnridakjxgq', 'trackAvailableForSubscription': True, 'trackAvailableForPurchase': True, 'albumAvailableForPurchase': False, 'explicitType': '2'}}]
2019-04-28 10:16:19.808515 INFO Google Music: --------------------------------------------

At least I know what I’m missing now. We’ll get it working yet! :smiley: