mirror of https://github.com/home-assistant/core
234 lines
6.8 KiB
Python
234 lines
6.8 KiB
Python
"""Support for Logitech UE Smart Radios."""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
import requests
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.components.media_player import (
|
|
PLATFORM_SCHEMA,
|
|
MediaPlayerEntity,
|
|
MediaPlayerEntityFeature,
|
|
)
|
|
from homeassistant.components.media_player.const import MEDIA_TYPE_MUSIC
|
|
from homeassistant.const import (
|
|
CONF_PASSWORD,
|
|
CONF_USERNAME,
|
|
STATE_IDLE,
|
|
STATE_OFF,
|
|
STATE_PAUSED,
|
|
STATE_PLAYING,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
import homeassistant.helpers.config_validation as cv
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
ICON = "mdi:radio"
|
|
URL = "http://decibel.logitechmusic.com/jsonrpc.js"
|
|
|
|
PLAYBACK_DICT = {"play": STATE_PLAYING, "pause": STATE_PAUSED, "stop": STATE_IDLE}
|
|
|
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|
{vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_PASSWORD): cv.string}
|
|
)
|
|
|
|
|
|
def send_request(payload, session):
|
|
"""Send request to radio."""
|
|
try:
|
|
request = requests.post(
|
|
URL,
|
|
cookies={"sdi_squeezenetwork_session": session},
|
|
json=payload,
|
|
timeout=5,
|
|
)
|
|
except requests.exceptions.Timeout:
|
|
_LOGGER.error("Timed out when sending request")
|
|
except requests.exceptions.ConnectionError:
|
|
_LOGGER.error("An error occurred while connecting")
|
|
else:
|
|
return request.json()
|
|
|
|
|
|
def setup_platform(
|
|
hass: HomeAssistant,
|
|
config: ConfigType,
|
|
add_entities: AddEntitiesCallback,
|
|
discovery_info: DiscoveryInfoType | None = None,
|
|
) -> None:
|
|
"""Set up the Logitech UE Smart Radio platform."""
|
|
email = config.get(CONF_USERNAME)
|
|
password = config.get(CONF_PASSWORD)
|
|
|
|
session_request = requests.post(
|
|
"https://www.uesmartradio.com/user/login",
|
|
data={"email": email, "password": password},
|
|
timeout=5,
|
|
)
|
|
session = session_request.cookies["sdi_squeezenetwork_session"]
|
|
|
|
player_request = send_request({"params": ["", ["serverstatus"]]}, session)
|
|
|
|
players = [
|
|
UERadioDevice(session, player["playerid"], player["name"])
|
|
for player in player_request["result"]["players_loop"]
|
|
]
|
|
|
|
add_entities(players)
|
|
|
|
|
|
class UERadioDevice(MediaPlayerEntity):
|
|
"""Representation of a Logitech UE Smart Radio device."""
|
|
|
|
_attr_supported_features = (
|
|
MediaPlayerEntityFeature.PLAY
|
|
| MediaPlayerEntityFeature.PAUSE
|
|
| MediaPlayerEntityFeature.STOP
|
|
| MediaPlayerEntityFeature.PREVIOUS_TRACK
|
|
| MediaPlayerEntityFeature.NEXT_TRACK
|
|
| MediaPlayerEntityFeature.TURN_ON
|
|
| MediaPlayerEntityFeature.TURN_OFF
|
|
| MediaPlayerEntityFeature.VOLUME_SET
|
|
| MediaPlayerEntityFeature.VOLUME_MUTE
|
|
)
|
|
|
|
def __init__(self, session, player_id, player_name):
|
|
"""Initialize the Logitech UE Smart Radio device."""
|
|
self._session = session
|
|
self._player_id = player_id
|
|
self._name = player_name
|
|
self._state = None
|
|
self._volume = 0
|
|
self._last_volume = 0
|
|
self._media_title = None
|
|
self._media_artist = None
|
|
self._media_artwork_url = None
|
|
|
|
def send_command(self, command):
|
|
"""Send command to radio."""
|
|
send_request(
|
|
{"method": "slim.request", "params": [self._player_id, command]},
|
|
self._session,
|
|
)
|
|
|
|
def update(self):
|
|
"""Get the latest details from the device."""
|
|
request = send_request(
|
|
{
|
|
"method": "slim.request",
|
|
"params": [
|
|
self._player_id,
|
|
["status", "-", 1, "tags:cgABbehldiqtyrSuoKLN"],
|
|
],
|
|
},
|
|
self._session,
|
|
)
|
|
|
|
if request["error"] is not None:
|
|
self._state = None
|
|
return
|
|
|
|
if request["result"]["power"] == 0:
|
|
self._state = STATE_OFF
|
|
else:
|
|
self._state = PLAYBACK_DICT[request["result"]["mode"]]
|
|
|
|
media_info = request["result"]["playlist_loop"][0]
|
|
|
|
self._volume = request["result"]["mixer volume"] / 100
|
|
self._media_artwork_url = media_info["artwork_url"]
|
|
self._media_title = media_info["title"]
|
|
if "artist" in media_info:
|
|
self._media_artist = media_info["artist"]
|
|
else:
|
|
self._media_artist = media_info.get("remote_title")
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the name of the device."""
|
|
return self._name
|
|
|
|
@property
|
|
def state(self):
|
|
"""Return the state of the device."""
|
|
return self._state
|
|
|
|
@property
|
|
def icon(self):
|
|
"""Return the icon to use in the frontend, if any."""
|
|
return ICON
|
|
|
|
@property
|
|
def is_volume_muted(self):
|
|
"""Boolean if volume is currently muted."""
|
|
return self._volume <= 0
|
|
|
|
@property
|
|
def volume_level(self):
|
|
"""Volume level of the media player (0..1)."""
|
|
return self._volume
|
|
|
|
@property
|
|
def media_content_type(self):
|
|
"""Return the media content type."""
|
|
return MEDIA_TYPE_MUSIC
|
|
|
|
@property
|
|
def media_image_url(self):
|
|
"""Image URL of current playing media."""
|
|
return self._media_artwork_url
|
|
|
|
@property
|
|
def media_artist(self):
|
|
"""Artist of current playing media, music track only."""
|
|
return self._media_artist
|
|
|
|
@property
|
|
def media_title(self):
|
|
"""Title of current playing media."""
|
|
return self._media_title
|
|
|
|
def turn_on(self):
|
|
"""Turn on specified media player or all."""
|
|
self.send_command(["power", 1])
|
|
|
|
def turn_off(self):
|
|
"""Turn off specified media player or all."""
|
|
self.send_command(["power", 0])
|
|
|
|
def media_play(self):
|
|
"""Send the media player the command for play/pause."""
|
|
self.send_command(["play"])
|
|
|
|
def media_pause(self):
|
|
"""Send the media player the command for pause."""
|
|
self.send_command(["pause"])
|
|
|
|
def media_stop(self):
|
|
"""Send the media player the stop command."""
|
|
self.send_command(["stop"])
|
|
|
|
def media_previous_track(self):
|
|
"""Send the media player the command for prev track."""
|
|
self.send_command(["button", "rew"])
|
|
|
|
def media_next_track(self):
|
|
"""Send the media player the command for next track."""
|
|
self.send_command(["button", "fwd"])
|
|
|
|
def mute_volume(self, mute):
|
|
"""Send mute command."""
|
|
if mute:
|
|
self._last_volume = self._volume
|
|
self.send_command(["mixer", "volume", 0])
|
|
else:
|
|
self.send_command(["mixer", "volume", self._last_volume * 100])
|
|
|
|
def set_volume_level(self, volume):
|
|
"""Set volume level, range 0..1."""
|
|
self.send_command(["mixer", "volume", volume * 100])
|