diff --git a/.coveragerc b/.coveragerc index 7a3978d04cc..aec863174b8 100644 --- a/.coveragerc +++ b/.coveragerc @@ -159,6 +159,7 @@ omit = homeassistant/components/sensor/glances.py homeassistant/components/sensor/google_travel_time.py homeassistant/components/sensor/gtfs.py + homeassistant/components/sensor/lastfm.py homeassistant/components/sensor/loopenergy.py homeassistant/components/sensor/netatmo.py homeassistant/components/sensor/neurio_energy.py diff --git a/homeassistant/components/sensor/lastfm.py b/homeassistant/components/sensor/lastfm.py new file mode 100644 index 00000000000..3001171081e --- /dev/null +++ b/homeassistant/components/sensor/lastfm.py @@ -0,0 +1,90 @@ +""" +Sensor for Last.fm account status. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.lastfm/ +""" +import re +from homeassistant.helpers.entity import Entity +from homeassistant.const import CONF_API_KEY + +ICON = 'mdi:lastfm' + +REQUIREMENTS = ['pylast==1.6.0'] + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the Last.fm platform.""" + import pylast as lastfm + network = lastfm.LastFMNetwork(api_key=config.get(CONF_API_KEY)) + add_devices( + [LastfmSensor(username, + network) for username in config.get("users", [])]) + + +class LastfmSensor(Entity): + """A class for the Last.fm account.""" + + # pylint: disable=abstract-method, too-many-instance-attributes + def __init__(self, user, lastfm): + """Initialize the sensor.""" + self._user = lastfm.get_user(user) + self._name = user + self._lastfm = lastfm + self._state = "Not Scrobbling" + self._playcount = None + self._lastplayed = None + self._topplayed = None + self._cover = None + self.update() + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def entity_id(self): + """Return the entity ID.""" + return 'sensor.lastfm_{}'.format(self._name) + + @property + def state(self): + """Return the state of the sensor.""" + return self._state + + # pylint: disable=no-member + def update(self): + """Update device state.""" + self._cover = self._user.get_image() + self._playcount = self._user.get_playcount() + last = self._user.get_recent_tracks(limit=2)[0] + self._lastplayed = "{} - {}".format(last.track.artist, + last.track.title) + top = self._user.get_top_tracks(limit=1)[0] + toptitle = re.search("', '(.+?)',", str(top)) + topartist = re.search("'(.+?)',", str(top)) + self._topplayed = "{} - {}".format(topartist.group(1), + toptitle.group(1)) + if self._user.get_now_playing() is None: + self._state = "Not Scrobbling" + return + now = self._user.get_now_playing() + self._state = "{} - {}".format(now.artist, now.title) + + @property + def device_state_attributes(self): + """Return the state attributes.""" + return {'Play Count': self._playcount, 'Last Played': + self._lastplayed, 'Top Played': self._topplayed} + + @property + def entity_picture(self): + """Avatar of the user.""" + return self._cover + + @property + def icon(self): + """Return the icon to use in the frontend.""" + return ICON diff --git a/requirements_all.txt b/requirements_all.txt index 90d88e0bcae..9a876cbe012 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -222,6 +222,9 @@ pyfttt==0.3 # homeassistant.components.device_tracker.icloud pyicloud==0.8.3 +# homeassistant.components.sensor.lastfm +pylast==1.6.0 + # homeassistant.components.sensor.loopenergy pyloopenergy==0.0.10