176 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
"""
 | 
						|
Support for Anthem Network Receivers and Processors.
 | 
						|
 | 
						|
For more details about this platform, please refer to the documentation at
 | 
						|
https://home-assistant.io/components/media_player.anthemav/
 | 
						|
"""
 | 
						|
import logging
 | 
						|
import asyncio
 | 
						|
 | 
						|
import voluptuous as vol
 | 
						|
 | 
						|
from homeassistant.components.media_player import (
 | 
						|
    PLATFORM_SCHEMA, SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_SELECT_SOURCE,
 | 
						|
    SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, MediaPlayerDevice)
 | 
						|
from homeassistant.const import (
 | 
						|
    CONF_NAME, CONF_HOST, CONF_PORT, STATE_OFF, STATE_ON, STATE_UNKNOWN,
 | 
						|
    EVENT_HOMEASSISTANT_STOP)
 | 
						|
import homeassistant.helpers.config_validation as cv
 | 
						|
 | 
						|
REQUIREMENTS = ['anthemav==1.1.7']
 | 
						|
 | 
						|
_LOGGER = logging.getLogger(__name__)
 | 
						|
 | 
						|
DOMAIN = 'anthemav'
 | 
						|
 | 
						|
DEFAULT_PORT = 14999
 | 
						|
 | 
						|
SUPPORT_ANTHEMAV = SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
 | 
						|
    SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_SELECT_SOURCE
 | 
						|
 | 
						|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
 | 
						|
    vol.Required(CONF_HOST): cv.string,
 | 
						|
    vol.Optional(CONF_NAME): cv.string,
 | 
						|
    vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
@asyncio.coroutine
 | 
						|
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
 | 
						|
    """Set up our socket to the AVR."""
 | 
						|
    import anthemav
 | 
						|
 | 
						|
    host = config.get(CONF_HOST)
 | 
						|
    port = config.get(CONF_PORT)
 | 
						|
    name = config.get(CONF_NAME)
 | 
						|
    device = None
 | 
						|
 | 
						|
    _LOGGER.info('Provisioning Anthem AVR device at %s:%d', host, port)
 | 
						|
 | 
						|
    def async_anthemav_update_callback(message):
 | 
						|
        """Receive notification from transport that new data exists."""
 | 
						|
        _LOGGER.info('Received update calback from AVR: %s', message)
 | 
						|
        hass.async_add_job(device.async_update_ha_state())
 | 
						|
 | 
						|
    avr = yield from anthemav.Connection.create(
 | 
						|
        host=host, port=port, loop=hass.loop,
 | 
						|
        update_callback=async_anthemav_update_callback)
 | 
						|
 | 
						|
    device = AnthemAVR(avr, name)
 | 
						|
 | 
						|
    _LOGGER.debug('dump_devicedata: '+device.dump_avrdata)
 | 
						|
    _LOGGER.debug('dump_conndata: '+avr.dump_conndata)
 | 
						|
    _LOGGER.debug('dump_rawdata: '+avr.protocol.dump_rawdata)
 | 
						|
 | 
						|
    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, device.avr.close)
 | 
						|
    yield from async_add_devices([device])
 | 
						|
 | 
						|
 | 
						|
class AnthemAVR(MediaPlayerDevice):
 | 
						|
    """Entity reading values from Anthem AVR protocol."""
 | 
						|
 | 
						|
    def __init__(self, avr, name):
 | 
						|
        """"Initialize entity with transport."""
 | 
						|
        super().__init__()
 | 
						|
        self.avr = avr
 | 
						|
        self._name = name
 | 
						|
 | 
						|
    def _lookup(self, propname, dval=None):
 | 
						|
        return getattr(self.avr.protocol, propname, dval)
 | 
						|
 | 
						|
    @property
 | 
						|
    def supported_media_commands(self):
 | 
						|
        """Return flag of media commands that are supported."""
 | 
						|
        return SUPPORT_ANTHEMAV
 | 
						|
 | 
						|
    @property
 | 
						|
    def should_poll(self):
 | 
						|
        """No polling needed."""
 | 
						|
        return False
 | 
						|
 | 
						|
    @property
 | 
						|
    def name(self):
 | 
						|
        """Return name of device."""
 | 
						|
        return self._name or self._lookup('model')
 | 
						|
 | 
						|
    @property
 | 
						|
    def state(self):
 | 
						|
        """Return state of power on/off."""
 | 
						|
        pwrstate = self._lookup('power')
 | 
						|
 | 
						|
        if pwrstate is True:
 | 
						|
            return STATE_ON
 | 
						|
        elif pwrstate is False:
 | 
						|
            return STATE_OFF
 | 
						|
        else:
 | 
						|
            return STATE_UNKNOWN
 | 
						|
 | 
						|
    @property
 | 
						|
    def is_volume_muted(self):
 | 
						|
        """Return boolean reflecting mute state on device."""
 | 
						|
        return self._lookup('mute', False)
 | 
						|
 | 
						|
    @property
 | 
						|
    def volume_level(self):
 | 
						|
        """Return volume level from 0 to 1."""
 | 
						|
        return self._lookup('volume_as_percentage', 0.0)
 | 
						|
 | 
						|
    @property
 | 
						|
    def media_title(self):
 | 
						|
        """Return current input name (closest we have to media title)."""
 | 
						|
        return self._lookup('input_name', 'No Source')
 | 
						|
 | 
						|
    @property
 | 
						|
    def app_name(self):
 | 
						|
        """Return details about current video and audio stream."""
 | 
						|
        return self._lookup('video_input_resolution_text', '') + ' ' \
 | 
						|
            + self._lookup('audio_input_name', '')
 | 
						|
 | 
						|
    @property
 | 
						|
    def source(self):
 | 
						|
        """Return currently selected input."""
 | 
						|
        return self._lookup('input_name', "Unknown")
 | 
						|
 | 
						|
    @property
 | 
						|
    def source_list(self):
 | 
						|
        """Return all active, configured inputs."""
 | 
						|
        return self._lookup('input_list', ["Unknown"])
 | 
						|
 | 
						|
    @asyncio.coroutine
 | 
						|
    def async_select_source(self, source):
 | 
						|
        """Change AVR to the designated source (by name)."""
 | 
						|
        self._update_avr('input_name', source)
 | 
						|
 | 
						|
    @asyncio.coroutine
 | 
						|
    def async_turn_off(self):
 | 
						|
        """Turn AVR power off."""
 | 
						|
        self._update_avr('power', False)
 | 
						|
 | 
						|
    @asyncio.coroutine
 | 
						|
    def async_turn_on(self):
 | 
						|
        """Turn AVR power on."""
 | 
						|
        self._update_avr('power', True)
 | 
						|
 | 
						|
    @asyncio.coroutine
 | 
						|
    def async_set_volume_level(self, volume):
 | 
						|
        """Set AVR volume (0 to 1)."""
 | 
						|
        self._update_avr('volume_as_percentage', volume)
 | 
						|
 | 
						|
    @asyncio.coroutine
 | 
						|
    def async_mute_volume(self, mute):
 | 
						|
        """Engage AVR mute."""
 | 
						|
        self._update_avr('mute', mute)
 | 
						|
 | 
						|
    def _update_avr(self, propname, value):
 | 
						|
        """Update a property in the AVR."""
 | 
						|
        _LOGGER.info('Sending command to AVR: set '+propname+' to '+str(value))
 | 
						|
        setattr(self.avr.protocol, propname, value)
 | 
						|
 | 
						|
    @property
 | 
						|
    def dump_avrdata(self):
 | 
						|
        """Return state of avr object for debugging forensics."""
 | 
						|
        attrs = vars(self)
 | 
						|
        return(
 | 
						|
            'dump_avrdata: '
 | 
						|
            + ', '.join('%s: %s' % item for item in attrs.items()))
 |