core/homeassistant/components/media_player/hdmi_cec.py

176 lines
6.1 KiB
Python

"""
Support for HDMI CEC devices as media players.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/hdmi_cec/
"""
import logging
from homeassistant.components.hdmi_cec import ATTR_NEW, CecDevice
from homeassistant.components.media_player import MediaPlayerDevice, DOMAIN, \
SUPPORT_TURN_ON, SUPPORT_TURN_OFF, SUPPORT_PLAY_MEDIA, SUPPORT_PAUSE, \
SUPPORT_PREVIOUS_TRACK, SUPPORT_NEXT_TRACK, SUPPORT_STOP, \
SUPPORT_VOLUME_STEP, SUPPORT_VOLUME_MUTE
from homeassistant.const import STATE_ON, STATE_OFF, STATE_PLAYING, \
STATE_IDLE, STATE_PAUSED
from homeassistant.core import HomeAssistant
DEPENDENCIES = ['hdmi_cec']
_LOGGER = logging.getLogger(__name__)
ENTITY_ID_FORMAT = DOMAIN + '.{}'
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Find and return HDMI devices as +switches."""
if ATTR_NEW in discovery_info:
_LOGGER.info("Setting up HDMI devices %s", discovery_info[ATTR_NEW])
add_devices(CecPlayerDevice(hass, hass.data.get(device),
hass.data.get(device).logical_address) for
device in discovery_info[ATTR_NEW])
class CecPlayerDevice(CecDevice, MediaPlayerDevice):
"""Representation of a HDMI device as a Media player."""
def __init__(self, hass: HomeAssistant, device, logical) -> None:
"""Initialize the HDMI device."""
CecDevice.__init__(self, hass, device, logical)
self.entity_id = "%s.%s_%s" % (
DOMAIN, 'hdmi', hex(self._logical_address)[2:])
self.update()
def send_keypress(self, key):
"""Send keypress to CEC adapter."""
from pycec.commands import KeyPressCommand, KeyReleaseCommand
_LOGGER.debug("Sending keypress %s to device %s", hex(key),
hex(self._logical_address))
self._device.send_command(
KeyPressCommand(key, dst=self._logical_address))
self._device.send_command(
KeyReleaseCommand(dst=self._logical_address))
def send_playback(self, key):
"""Send playback status to CEC adapter."""
from pycec.commands import CecCommand
self._device.async_send_command(
CecCommand(key, dst=self._logical_address))
def mute_volume(self, mute):
"""Mute volume."""
from pycec.const import KEY_MUTE_TOGGLE
self.send_keypress(KEY_MUTE_TOGGLE)
def media_previous_track(self):
"""Go to previous track."""
from pycec.const import KEY_BACKWARD
self.send_keypress(KEY_BACKWARD)
def turn_on(self):
"""Turn device on."""
self._device.turn_on()
self._state = STATE_ON
def clear_playlist(self):
"""Clear players playlist."""
raise NotImplementedError()
def turn_off(self):
"""Turn device off."""
self._device.turn_off()
self._state = STATE_OFF
def media_stop(self):
"""Stop playback."""
from pycec.const import KEY_STOP
self.send_keypress(KEY_STOP)
self._state = STATE_IDLE
def play_media(self, media_type, media_id, **kwargs):
"""Not supported."""
raise NotImplementedError()
def media_next_track(self):
"""Skip to next track."""
from pycec.const import KEY_FORWARD
self.send_keypress(KEY_FORWARD)
def media_seek(self, position):
"""Not supported."""
raise NotImplementedError()
def set_volume_level(self, volume):
"""Set volume level, range 0..1."""
raise NotImplementedError()
def media_pause(self):
"""Pause playback."""
from pycec.const import KEY_PAUSE
self.send_keypress(KEY_PAUSE)
self._state = STATE_PAUSED
def select_source(self, source):
"""Not supported."""
raise NotImplementedError()
def media_play(self):
"""Start playback."""
from pycec.const import KEY_PLAY
self.send_keypress(KEY_PLAY)
self._state = STATE_PLAYING
def volume_up(self):
"""Increase volume."""
from pycec.const import KEY_VOLUME_UP
_LOGGER.debug("%s: volume up", self._logical_address)
self.send_keypress(KEY_VOLUME_UP)
def volume_down(self):
"""Decrease volume."""
from pycec.const import KEY_VOLUME_DOWN
_LOGGER.debug("%s: volume down", self._logical_address)
self.send_keypress(KEY_VOLUME_DOWN)
@property
def state(self) -> str:
"""Cache state of device."""
return self._state
def _update(self, device=None):
"""Update device status."""
if device:
from pycec.const import STATUS_PLAY, STATUS_STOP, STATUS_STILL, \
POWER_OFF, POWER_ON
if device.power_status == POWER_OFF:
self._state = STATE_OFF
elif not self.support_pause:
if device.power_status == POWER_ON:
self._state = STATE_ON
elif device.status == STATUS_PLAY:
self._state = STATE_PLAYING
elif device.status == STATUS_STOP:
self._state = STATE_IDLE
elif device.status == STATUS_STILL:
self._state = STATE_PAUSED
else:
_LOGGER.warning("Unknown state: %s", device.status)
self.schedule_update_ha_state()
@property
def supported_features(self):
"""Flag media player features that are supported."""
from pycec.const import TYPE_RECORDER, TYPE_PLAYBACK, TYPE_TUNER, \
TYPE_AUDIO
if self.type_id == TYPE_RECORDER or self.type == TYPE_PLAYBACK:
return (SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PLAY_MEDIA |
SUPPORT_PAUSE | SUPPORT_STOP | SUPPORT_PREVIOUS_TRACK |
SUPPORT_NEXT_TRACK)
if self.type == TYPE_TUNER:
return (SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PLAY_MEDIA |
SUPPORT_PAUSE | SUPPORT_STOP)
if self.type_id == TYPE_AUDIO:
return (SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_VOLUME_STEP |
SUPPORT_VOLUME_MUTE)
return SUPPORT_TURN_ON | SUPPORT_TURN_OFF