""" 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): """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