Vlc telnet (#24290)

* Vlc telnet first commit

First functional version, remains to add more functionality.

* New functions added and bugfixes

* Compliance with dev checklist

* Compliance with dev checklist

* Compliance with pydocstyle

* Removed unused import

* Fixed wrong reference for exception

* Module renamed

* Fixed module rename in other

* Fixed wrong reference for exception


Module renamed


Fixed module rename in other

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Suggestions by @OttoWinter

+Manage error when the VLC dissapears to show status unavailable.

* Removed error log, instead set unavailable state

* Changes suggested by @pvizeli

-Import location
-Use of constants

* Implemented available method

* Improved available method
This commit is contained in:
Rodrigo Pérez 2019-06-21 06:13:47 -03:00 committed by Pascal Vizeli
parent 6bc636c2f2
commit d468d0f71b
6 changed files with 249 additions and 0 deletions

View File

@ -665,6 +665,7 @@ omit =
homeassistant/components/viaggiatreno/sensor.py
homeassistant/components/vizio/media_player.py
homeassistant/components/vlc/media_player.py
homeassistant/components/vlc_telnet/media_player.py
homeassistant/components/volkszaehler/sensor.py
homeassistant/components/volumio/media_player.py
homeassistant/components/volvooncall/*

View File

@ -276,6 +276,7 @@ homeassistant/components/utility_meter/* @dgomes
homeassistant/components/velux/* @Julius2342
homeassistant/components/version/* @fabaff
homeassistant/components/vizio/* @raman325
homeassistant/components/vlc_telnet/* @rodripf
homeassistant/components/waqi/* @andrey-git
homeassistant/components/watson_tts/* @rutkai
homeassistant/components/weather/* @fabaff

View File

@ -0,0 +1 @@
"""The vlc component."""

View File

@ -0,0 +1,10 @@
{
"domain": "vlc_telnet",
"name": "VLC telnet",
"documentation": "https://www.home-assistant.io/components/vlc-telnet",
"requirements": [
"python-telnet-vlc==1.0.4"
],
"dependencies": [],
"codeowners": ["@rodripf"]
}

View File

@ -0,0 +1,233 @@
"""Provide functionality to interact with the vlc telnet interface."""
import logging
import voluptuous as vol
from python_telnet_vlc import VLCTelnet, ConnectionError as ConnErr
from homeassistant.components.media_player import (
MediaPlayerDevice, PLATFORM_SCHEMA)
from homeassistant.components.media_player.const import (
MEDIA_TYPE_MUSIC, SUPPORT_PAUSE, SUPPORT_PLAY,
SUPPORT_PLAY_MEDIA, SUPPORT_STOP, SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_SET, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
SUPPORT_NEXT_TRACK, SUPPORT_CLEAR_PLAYLIST, SUPPORT_SHUFFLE_SET)
from homeassistant.const import (
CONF_NAME, STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_UNAVAILABLE,
CONF_HOST, CONF_PORT, CONF_PASSWORD)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'vlc_telnet'
DEFAULT_NAME = 'VLC-TELNET'
DEFAULT_PORT = 4212
SUPPORT_VLC = SUPPORT_PAUSE | SUPPORT_SEEK | SUPPORT_VOLUME_SET \
| SUPPORT_VOLUME_MUTE | SUPPORT_PREVIOUS_TRACK \
| SUPPORT_NEXT_TRACK | SUPPORT_PLAY_MEDIA | SUPPORT_STOP \
| SUPPORT_CLEAR_PLAYLIST | SUPPORT_PLAY \
| SUPPORT_SHUFFLE_SET
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.positive_int,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the vlc platform."""
add_entities([VlcDevice(config.get(CONF_NAME),
config.get(CONF_HOST),
config.get(CONF_PORT),
config.get(CONF_PASSWORD))], True)
class VlcDevice(MediaPlayerDevice):
"""Representation of a vlc player."""
def __init__(self, name, host, port, passwd):
"""Initialize the vlc device."""
self._instance = None
self._name = name
self._volume = None
self._muted = None
self._state = STATE_UNAVAILABLE
self._media_position_updated_at = None
self._media_position = None
self._media_duration = None
self._host = host
self._port = port
self._password = passwd
self._vlc = None
self._available = False
self._volume_bkp = 0
self._media_artist = ""
self._media_title = ""
def update(self):
"""Get the latest details from the device."""
if self._vlc is None:
try:
self._vlc = VLCTelnet(self._host, self._password, self._port)
self._state = STATE_IDLE
self._available = True
except (ConnErr, EOFError):
self._available = False
self._vlc = None
else:
try:
status = self._vlc.status()
if status:
if 'volume' in status:
self._volume = int(status['volume']) / 500.0
else:
self._volume = None
if 'state' in status:
state = status["state"]
if state == "playing":
self._state = STATE_PLAYING
elif state == "paused":
self._state = STATE_PAUSED
else:
self._state = STATE_IDLE
else:
self._state = STATE_IDLE
self._media_duration = self._vlc.get_length()
self._media_position = self._vlc.get_time()
info = self._vlc.info()
if info:
self._media_artist = info[0].get('artist')
self._media_title = info[0].get('title')
except (ConnErr, EOFError):
self._available = False
self._vlc = None
return True
@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 available(self) -> bool:
"""Return True if entity is available."""
return self._available
@property
def volume_level(self):
"""Volume level of the media player (0..1)."""
return self._volume
@property
def is_volume_muted(self):
"""Boolean if volume is currently muted."""
return self._muted
@property
def supported_features(self):
"""Flag media player features that are supported."""
return SUPPORT_VLC
@property
def media_content_type(self):
"""Content type of current playing media."""
return MEDIA_TYPE_MUSIC
@property
def media_duration(self):
"""Duration of current playing media in seconds."""
return self._media_duration
@property
def media_position(self):
"""Position of current playing media in seconds."""
return self._media_position
@property
def media_position_updated_at(self):
"""When was the position of the current playing media valid."""
return self._media_position_updated_at
@property
def media_title(self):
"""Title of current playing media."""
return self._media_title
@property
def media_artist(self):
"""Artist of current playing media, music track only."""
return self._media_artist
def media_seek(self, position):
"""Seek the media to a specific location."""
track_length = self._vlc.get_length() / 1000
self._vlc.seek(position / track_length)
def mute_volume(self, mute):
"""Mute the volume."""
if mute:
self._volume_bkp = self._volume
self._volume = 0
self._vlc.set_volume("0")
else:
self._vlc.set_volume(str(self._volume_bkp))
self._volume = self._volume_bkp
self._muted = mute
def set_volume_level(self, volume):
"""Set volume level, range 0..1."""
self._vlc.set_volume(str(volume * 500))
self._volume = volume
def media_play(self):
"""Send play command."""
self._vlc.play()
self._state = STATE_PLAYING
def media_pause(self):
"""Send pause command."""
self._vlc.pause()
self._state = STATE_PAUSED
def media_stop(self):
"""Send stop command."""
self._vlc.stop()
self._state = STATE_IDLE
def play_media(self, media_type, media_id, **kwargs):
"""Play media from a URL or file."""
if media_type != MEDIA_TYPE_MUSIC:
_LOGGER.error(
"Invalid media type %s. Only %s is supported",
media_type, MEDIA_TYPE_MUSIC)
return
self._vlc.add(media_id)
self._state = STATE_PLAYING
def media_previous_track(self):
"""Send previous track command."""
self._vlc.prev()
def media_next_track(self):
"""Send next track command."""
self._vlc.next()
def clear_playlist(self):
"""Clear players playlist."""
self._vlc.clear()
def set_shuffle(self, shuffle):
"""Enable/disable shuffle mode."""
self._vlc.random(shuffle)

View File

@ -1477,6 +1477,9 @@ python-tado==0.2.9
# homeassistant.components.telegram_bot
python-telegram-bot==11.1.0
# homeassistant.components.vlc_telnet
python-telnet-vlc==1.0.4
# homeassistant.components.twitch
python-twitch-client==0.6.0