-1

I am trying to setup the itunes Media Player in HASSio. I have the REST API running on my mac, and I am able to pull it up in my browser and see that it is running. From within HA, I am able to adjust the volume and change to the next song, however it will not tell me what is currently playing. the below code is what is output to the log whenever I try and do anything adjust volume, start/stop, forward/reverse.

HASS - 0.84.6

ITUNES - 12.2.1.16

ERROR (MainThread) [homeassistant.components.media_player] Error while setting up platform itunes
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
      SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
      return fut.result()
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
      result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/itunes.py", line 169, in setup_platform
      add_entities
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/itunes.py", line 199, in __init__
      self.update()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/itunes.py", line 237, in update
      now_playing = self.client.now_playing()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/itunes.py", line 92, in now_playing
      return self._request('GET', '/now_playing')
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/itunes.py", line 80, in _request
      return response.json()
  File "/usr/local/lib/python3.6/site-packages/requests/models.py", line 897, in json
      return complexjson.loads(self.text, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/simplejson/__init__.py", line 518, in loads
      return _default_decoder.decode(s)
  File "/usr/local/lib/python3.6/site-packages/simplejson/decoder.py", line 370, in decode
      obj, end = self.raw_decode(s)
  File "/usr/local/lib/python3.6/site-packages/simplejson/decoder.py", line 400, in raw_decode
      return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Here is Lines 66-171 of itunes.py

def _request(self, method, path, params=None):
    """Make the actual request and return the parsed response."""
    url = '{}{}'.format(self._base_url, path)

    try:
        if method == 'GET':
            response = requests.get(url, timeout=DEFAULT_TIMEOUT)
        elif method == 'POST':
            response = requests.put(url, params, timeout=DEFAULT_TIMEOUT)
        elif method == 'PUT':
            response = requests.put(url, params, timeout=DEFAULT_TIMEOUT)
        elif method == 'DELETE':
            response = requests.delete(url, timeout=DEFAULT_TIMEOUT)

        return response.json()
    except requests.exceptions.HTTPError:
        return {'player_state': 'error'}
    except requests.exceptions.RequestException:
        return {'player_state': 'offline'}

def _command(self, named_command):
    """Make a request for a controlling command."""
    return self._request('PUT', '/' + named_command)

def now_playing(self):
    """Return the current state."""
    return self._request('GET', '/now_playing')

def set_volume(self, level):
    """Set the volume and returns the current state, level 0-100."""
    return self._request('PUT', '/volume', {'level': level})

def set_muted(self, muted):
    """Mute and returns the current state, muted True or False."""
    return self._request('PUT', '/mute', {'muted': muted})

def play(self):
    """Set playback to play and returns the current state."""
    return self._command('play')

def pause(self):
    """Set playback to paused and returns the current state."""
    return self._command('pause')

def next(self):
    """Skip to the next track and returns the current state."""
    return self._command('next')

def previous(self):
    """Skip back and returns the current state."""
    return self._command('previous')

def stop(self):
    """Stop playback and return the current state."""
    return self._command('stop')

def play_playlist(self, playlist_id_or_name):
    """Set a playlist to be current and returns the current state."""
    response = self._request('GET', '/playlists')
    playlists = response.get('playlists', [])

    found_playlists = \
        [playlist for playlist in playlists if
         (playlist_id_or_name in [playlist["name"], playlist["id"]])]

    if found_playlists:
        playlist = found_playlists[0]
        path = '/playlists/' + playlist['id'] + '/play'
        return self._request('PUT', path)

def artwork_url(self):
    """Return a URL of the current track's album art."""
    return self._base_url + '/artwork'

def airplay_devices(self):
    """Return a list of AirPlay devices."""
    return self._request('GET', '/airplay_devices')

def airplay_device(self, device_id):
    """Return an AirPlay device."""
    return self._request('GET', '/airplay_devices/' + device_id)

def toggle_airplay_device(self, device_id, toggle):
    """Toggle airplay device on or off, id, toggle True or False."""
    command = 'on' if toggle else 'off'
    path = '/airplay_devices/' + device_id + '/' + command
    return self._request('PUT', path)

def set_volume_airplay_device(self, device_id, level):
    """Set volume, returns current state of device, id,level 0-100."""
    path = '/airplay_devices/' + device_id + '/volume'
    return self._request('PUT', path, {'level': level})


def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the iTunes platform."""
add_entities([
    ItunesDevice(
        config.get(CONF_NAME),
        config.get(CONF_HOST),
        config.get(CONF_PORT),
        config.get(CONF_SSL),

        add_entities
    )
])
nikedude
  • 13
  • 4
  • 2
    Print the contents of `/now_playing` - it's not valid JSON, which is why the decoder is complaining. – Danielle M. Dec 30 '18 at 20:54
  • _Guess_; you have JSONLines format. It's failing on the first character of the second line, a decent indicator. – roganjosh Dec 30 '18 at 20:58
  • 1
    Regardless, without the content that isn't valid JSON included as part of the question, how are we supposed to know *why* it isn't valid JSON? (roganjosh's guess *is* a solid one, but the question is incomplete). – Charles Duffy Dec 30 '18 at 20:59
  • 2
    We weren't asking for more code, we were asking for a small part of the putative JSON contents – roganjosh Dec 30 '18 at 21:04
  • 1
    (...well, a small part, but complete enough to fail parsing in the same way, as described in [mcve] guidelines -- similarly, the question should include only the **shortest** code that fails with the exact same error when parsing that JSON -- ideally, simplified to not do anything web-server / web-request-related at all, if you can generate the same problem just by hardcoding the content that fails to parse as a string; pay close attention to *both* the "minimal" and "complete"/"verifiable" parts of that specification). – Charles Duffy Dec 30 '18 at 21:20

1 Answers1

-1

Mac OS Sierra only came installed with a Python 2.XX. Upgrading to Python 3.6X seems to have it working.

nikedude
  • 13
  • 4