Skip to content
Snippets Groups Projects
Commit 880f18a3 authored by Diogo Gomes's avatar Diogo Gomes Committed by Tod Schmidt
Browse files

Mediaroom (#11864)

* make port mapping optional

* dependencies + improvements

* Added bytes and packets sensors from IGD

* flake8 check

* new sensor with upnp counters

* checks

* whitespaces in blank line

* requirements update

* added sensor.upnp to .coveragerc

* downgrade miniupnpc

Latest version of miniupnpc is 2.0, but pypi only has 1.9

Fortunately it is enough

* revert to non async

miniupnpc will do network calls, so this component can’t be moved to
coroutine

* hof hof

forgot to remove import ot asyncio

* Add baudrate option

* merge

* Added Mediaroom media_player component

* Updated header

Works with MEO and VDF set-top boxes in Portugal

* formatting

* Development Checklist (done)

* fix formatting according to houndci-bot

* more format fixing (tks houndci-bot)

* more fixes

* too much cleanup...

* too much

* pylint check

* Initial commit

Basic configuration testing

* flake8 and lint
parent f7c97874
No related branches found
No related tags found
No related merge requests found
......@@ -439,6 +439,7 @@ omit =
homeassistant/components/media_player/kodi.py
homeassistant/components/media_player/lg_netcast.py
homeassistant/components/media_player/liveboxplaytv.py
homeassistant/components/media_player/mediaroom.py
homeassistant/components/media_player/mpchc.py
homeassistant/components/media_player/mpd.py
homeassistant/components/media_player/nad.py
......
"""
Support for the Mediaroom Set-up-box.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.mediaroom/
"""
import logging
import voluptuous as vol
from homeassistant.components.media_player import (
MEDIA_TYPE_CHANNEL, SUPPORT_PAUSE, SUPPORT_PLAY_MEDIA,
SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_STOP, PLATFORM_SCHEMA,
SUPPORT_NEXT_TRACK, SUPPORT_PREVIOUS_TRACK, SUPPORT_PLAY,
SUPPORT_VOLUME_STEP, SUPPORT_VOLUME_MUTE,
MediaPlayerDevice)
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_OPTIMISTIC, CONF_TIMEOUT,
STATE_PAUSED, STATE_PLAYING, STATE_STANDBY,
STATE_ON)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pymediaroom==0.5']
_LOGGER = logging.getLogger(__name__)
NOTIFICATION_TITLE = 'Mediaroom Media Player Setup'
NOTIFICATION_ID = 'mediaroom_notification'
DEFAULT_NAME = 'Mediaroom STB'
DEFAULT_TIMEOUT = 9
KNOWN_HOSTS = []
SUPPORT_MEDIAROOM = SUPPORT_PAUSE | SUPPORT_TURN_ON | SUPPORT_TURN_OFF | \
SUPPORT_VOLUME_STEP | SUPPORT_VOLUME_MUTE | \
SUPPORT_PLAY_MEDIA | SUPPORT_STOP | SUPPORT_NEXT_TRACK | \
SUPPORT_PREVIOUS_TRACK | SUPPORT_PLAY
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Mediaroom platform."""
hosts = []
host = config.get(CONF_HOST, None)
if host is None:
_LOGGER.info("Trying to discover Mediaroom STB")
from pymediaroom import Remote
host = Remote.discover(KNOWN_HOSTS)
if host is None:
# Can't find any STB
return False
hosts.append(host)
KNOWN_HOSTS.append(host)
stbs = []
try:
for host in hosts:
stbs.append(MediaroomDevice(
config.get(CONF_NAME),
host,
config.get(CONF_OPTIMISTIC),
config.get(CONF_TIMEOUT)
))
except ConnectionRefusedError:
hass.components.persistent_notification.create(
'Error: Unable to initialize mediaroom at {}<br />'
'Check its network connection or consider '
'using auto discovery.<br />'
'You will need to restart hass after fixing.'
''.format(host),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
add_devices(stbs)
return True
class MediaroomDevice(MediaPlayerDevice):
"""Representation of a Mediaroom set-up-box on the network."""
def __init__(self, name, host, optimistic=False, timeout=DEFAULT_TIMEOUT):
"""Initialize the device."""
from pymediaroom import Remote
self.stb = Remote(host, timeout=timeout)
_LOGGER.info(
"Found %s at %s%s", name, host,
" - I'm optimistic" if optimistic else "")
self._name = name
self._is_standby = not optimistic
self._current = None
self._optimistic = optimistic
self._state = STATE_STANDBY
def update(self):
"""Retrieve latest state."""
if not self._optimistic:
self._is_standby = self.stb.get_standby()
if self._is_standby:
self._state = STATE_STANDBY
elif self._state not in [STATE_PLAYING, STATE_PAUSED]:
self._state = STATE_PLAYING
_LOGGER.debug(
"%s(%s) is [%s]",
self._name, self.stb.stb_ip, self._state)
def play_media(self, media_type, media_id, **kwargs):
"""Play media."""
_LOGGER.debug(
"%s(%s) Play media: %s (%s)",
self._name, self.stb.stb_ip, media_id, media_type)
if media_type != MEDIA_TYPE_CHANNEL:
_LOGGER.error('invalid media type')
return
if media_id.isdigit():
media_id = int(media_id)
else:
return
self.stb.send_cmd(media_id)
self._state = STATE_PLAYING
@property
def name(self):
"""Return the name of the device."""
return self._name
# MediaPlayerDevice properties and methods
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def supported_features(self):
"""Flag media player features that are supported."""
return SUPPORT_MEDIAROOM
@property
def media_content_type(self):
"""Return the content type of current playing media."""
return MEDIA_TYPE_CHANNEL
def turn_on(self):
"""Turn on the receiver."""
self.stb.send_cmd('Power')
self._state = STATE_ON
def turn_off(self):
"""Turn off the receiver."""
self.stb.send_cmd('Power')
self._state = STATE_STANDBY
def media_play(self):
"""Send play command."""
_LOGGER.debug("media_play()")
self.stb.send_cmd('PlayPause')
self._state = STATE_PLAYING
def media_pause(self):
"""Send pause command."""
self.stb.send_cmd('PlayPause')
self._state = STATE_PAUSED
def media_stop(self):
"""Send stop command."""
self.stb.send_cmd('Stop')
self._state = STATE_PAUSED
def media_previous_track(self):
"""Send Program Down command."""
self.stb.send_cmd('ProgDown')
self._state = STATE_PLAYING
def media_next_track(self):
"""Send Program Up command."""
self.stb.send_cmd('ProgUp')
self._state = STATE_PLAYING
def volume_up(self):
"""Send volume up command."""
self.stb.send_cmd('VolUp')
def volume_down(self):
"""Send volume up command."""
self.stb.send_cmd('VolDown')
def mute_volume(self, mute):
"""Send mute command."""
self.stb.send_cmd('Mute')
......@@ -789,6 +789,9 @@ pylutron==0.1.0
# homeassistant.components.notify.mailgun
pymailgunner==1.4
# homeassistant.components.media_player.mediaroom
pymediaroom==0.5
# homeassistant.components.mochad
pymochad==0.2.0
......
"""The tests for the mediaroom media_player."""
import unittest
from homeassistant.setup import setup_component
import homeassistant.components.media_player as media_player
from tests.common import (
assert_setup_component, get_test_home_assistant)
class TestMediaroom(unittest.TestCase):
"""Tests the Mediaroom Component."""
def setUp(self):
"""Initialize values for this test case class."""
self.hass = get_test_home_assistant()
def tearDown(self): # pylint: disable=invalid-name
"""Stop everything that we started."""
self.hass.stop()
def test_mediaroom_config(self):
"""Test set up the platform with basic configuration."""
config = {
media_player.DOMAIN: {
'platform': 'mediaroom',
'name': 'Living Room'
}
}
with assert_setup_component(1, media_player.DOMAIN) as result_config:
assert setup_component(self.hass, media_player.DOMAIN, config)
assert result_config[media_player.DOMAIN]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment