Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 95 additions & 10 deletions homeassistant/components/harman_kardon_avr/media_player.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Support for interface with an Harman/Kardon or JBL AVR."""

import logging
import time

import voluptuous as vol

Expand All @@ -8,23 +10,42 @@
MediaPlayerDevice, PLATFORM_SCHEMA)
from homeassistant.components.media_player.const import (
SUPPORT_TURN_OFF, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP,
SUPPORT_TURN_ON, SUPPORT_SELECT_SOURCE)
SUPPORT_TURN_ON, SUPPORT_SELECT_SOURCE, SUPPORT_VOLUME_SET)
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_PORT, STATE_OFF, STATE_ON)
CONF_HOST, CONF_NAME, CONF_PORT, CONF_SOURCE, STATE_OFF, STATE_ON)

_LOGGER = logging.getLogger(__name__)

CONF_KEY_INTERVAL = 'key_interval'
CONF_SIMULATE_VOLUME_SET = 'simulate_volume_set'
CONF_SOURCES = 'sources'

DEFAULT_NAME = 'Harman Kardon AVR'
DEFAULT_PORT = 10025
DEFAULT_KEY_INTERVAL = 0.2
DEFAULT_SIMULATE_VOLUME_SET = False
DEFAULT_SOURCES = [{"name": "STB"}, {"name": "Radio"}, {"name": "TV"},
{"name": "Game"}, {"name": "AUX"}]

SUPPORT_HARMAN_KARDON_AVR = SUPPORT_VOLUME_STEP | SUPPORT_VOLUME_MUTE | \
SUPPORT_TURN_OFF | SUPPORT_TURN_ON | \
SUPPORT_SELECT_SOURCE

SOURCE_SCHEMA = vol.Schema({
vol.Required(CONF_SOURCE): cv.string,
vol.Optional(CONF_NAME): cv.string
})

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_KEY_INTERVAL, default=DEFAULT_KEY_INTERVAL):
cv.small_float,
vol.Optional(CONF_SIMULATE_VOLUME_SET,
default=DEFAULT_SIMULATE_VOLUME_SET): cv.boolean,
vol.Optional(CONF_SOURCES, default=DEFAULT_SOURCES):
vol.All(cv.ensure_list, [SOURCE_SCHEMA])
})


Expand All @@ -35,42 +56,59 @@ def setup_platform(hass, config, add_entities, discover_info=None):
name = config[CONF_NAME]
host = config[CONF_HOST]
port = config[CONF_PORT]
key_interval = config[CONF_KEY_INTERVAL]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a use for this either, and it's only used for the fake volume? We should drop it.

simulate_volume_set = config[CONF_SIMULATE_VOLUME_SET]
sources = config[CONF_SOURCES]

avr = hkavr.HkAVR(host, port, name)
avr_device = HkAvrDevice(avr)
avr_device = HkAvrDevice(avr, key_interval, sources, simulate_volume_set)

add_entities([avr_device], True)


class HkAvrDevice(MediaPlayerDevice):
"""Representation of a Harman Kardon AVR / JBL AVR TV."""

def __init__(self, avr):
def __init__(self, avr, key_interval, sources, simulate_volume_set):
"""Initialize a new HarmanKardonAVR."""
self._avr = avr

self._name = avr.name
self._host = avr.host
self._port = avr.port
self._key_interval = key_interval

self._volume = 0.5

self._simulate_volume_set = simulate_volume_set

self._source_list = avr.sources
_sources = []
for entry in sources:
if CONF_NAME in entry:
_sources.append(entry[CONF_NAME])
else:
_sources.append(entry[CONF_SOURCE])

self._sources = _sources
self._source_mapping = sources

self._state = None
self._muted = avr.muted
self._current_source = avr.current_source

def update(self):
"""Update the state of this media_player."""
self._muted = self._avr.muted
self._current_source = self._avr.current_source

if self._avr.is_on():
self._state = STATE_ON
elif self._avr.is_off():
self._state = STATE_OFF
else:
self._avr.send_command("HEARTBEAT")
self._state = None

self._muted = self._avr.muted
self._current_source = self._avr.current_source

@property
def name(self):
"""Return the name of the device."""
Expand All @@ -86,6 +124,14 @@ def is_volume_muted(self):
"""Muted status not available."""
return self._muted

@property
def volume_level(self):
"""Return the volume level."""
if not self._simulate_volume_set:
raise NotImplementedError

return self._volume

@property
def source(self):
"""Return the current input source."""
Expand All @@ -94,11 +140,13 @@ def source(self):
@property
def source_list(self):
"""Available sources."""
return self._source_list
return self._sources
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not allow overriding the sources via the config. What is wrong with the options that come from the API?


@property
def supported_features(self):
"""Flag media player features that are supported."""
if self._simulate_volume_set:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't add this.

return SUPPORT_HARMAN_KARDON_AVR | SUPPORT_VOLUME_SET
return SUPPORT_HARMAN_KARDON_AVR

def turn_on(self):
Expand All @@ -111,7 +159,15 @@ def turn_off(self):

def select_source(self, source):
"""Select input source."""
return self._avr.select_source(source)
_avr_source = source

# Find the source key as given in the configuration
for src in self._source_mapping:
if src[CONF_NAME] is source:
_avr_source = src[CONF_SOURCE]
break

return self._avr.select_source(_avr_source)

def volume_up(self):
"""Volume up the AVR."""
Expand All @@ -121,6 +177,35 @@ def volume_down(self):
"""Volume down AVR."""
return self._avr.volume_down()

def set_volume_level(self, volume):
"""Set the volume level."""
if not self._simulate_volume_set:
raise NotImplementedError

_volume = volume * 100.0

_func = self.volume_up if _volume > 50 else self.volume_down

_steps = 1
if _volume > 90:
_steps = 5
elif _volume > 70:
_steps = 3
elif _volume > 50:
_steps = 1
elif _volume == 50:
_steps = 0
elif _volume > 30:
_steps = 1
elif _volume > 10:
_steps = 3
else:
_steps = 5

for _ in range(_steps):
_func()
time.sleep(self._key_interval)

def mute_volume(self, mute):
"""Send mute command."""
return self._avr.mute(mute)