From 2ac23c8be62e5e26d88cf1d872abdcd159e20215 Mon Sep 17 00:00:00 2001 From: Pawel Date: Wed, 13 Jun 2018 07:28:59 +0200 Subject: [PATCH] Epson projector support (#14841) * Epson projector support. Version based on external library * Epson projector support. Version based on external library * modified epson according to MartinHjelmare review. Added description of cmode to services.yaml * renamed EPSON_SCHEMA to epson_schema * removed method of getting cmode property * removed unnecessary checks change name of cmode service * renamed SERVICE_ATTR_CMODE to SERVICE_SELECT_CMODE --- .coveragerc | 1 + .../components/media_player/epson.py | 211 ++++++++++++++++++ .../components/media_player/services.yaml | 10 + requirements_all.txt | 3 + 4 files changed, 225 insertions(+) create mode 100644 homeassistant/components/media_player/epson.py diff --git a/.coveragerc b/.coveragerc index c4aea0e140a..693ca12d10e 100644 --- a/.coveragerc +++ b/.coveragerc @@ -490,6 +490,7 @@ omit = homeassistant/components/media_player/directv.py homeassistant/components/media_player/dunehd.py homeassistant/components/media_player/emby.py + homeassistant/components/media_player/epson.py homeassistant/components/media_player/firetv.py homeassistant/components/media_player/frontier_silicon.py homeassistant/components/media_player/gpmdp.py diff --git a/homeassistant/components/media_player/epson.py b/homeassistant/components/media_player/epson.py new file mode 100644 index 00000000000..b22234a4094 --- /dev/null +++ b/homeassistant/components/media_player/epson.py @@ -0,0 +1,211 @@ +""" +Support for Epson projector. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/media_player.epson/ +""" +import logging +import voluptuous as vol + +from homeassistant.components.media_player import ( + DOMAIN, MEDIA_PLAYER_SCHEMA, PLATFORM_SCHEMA, SUPPORT_NEXT_TRACK, + SUPPORT_PREVIOUS_TRACK, SUPPORT_SELECT_SOURCE, SUPPORT_TURN_OFF, + SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, + MediaPlayerDevice) +from homeassistant.const import ( + ATTR_ENTITY_ID, CONF_HOST, CONF_NAME, CONF_PORT, CONF_SSL, STATE_OFF, + STATE_ON) +from homeassistant.helpers.aiohttp_client import async_get_clientsession +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['epson-projector==0.1.3'] + +DATA_EPSON = 'epson' +DEFAULT_NAME = 'EPSON Projector' + +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=80): cv.port, + vol.Optional(CONF_SSL, default=False): cv.boolean +}) + +SERVICE_SELECT_CMODE = 'epson_select_cmode' +ATTR_CMODE = 'cmode' +SUPPORT_CMODE = 33001 + +SUPPORT_EPSON = SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_SELECT_SOURCE |\ + SUPPORT_CMODE | SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_STEP | \ + SUPPORT_NEXT_TRACK | SUPPORT_PREVIOUS_TRACK +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_platform(hass, config, async_add_devices, + discovery_info=None): + """Set up the Epson media player platform.""" + if DATA_EPSON not in hass.data: + hass.data[DATA_EPSON] = [] + name = config.get(CONF_NAME) + host = config.get(CONF_HOST) + + epson = EpsonProjector(async_get_clientsession(hass, verify_ssl=False), + name, host, + config.get(CONF_PORT), config.get(CONF_SSL)) + hass.data[DATA_EPSON].append(epson) + async_add_devices([epson], update_before_add=True) + + async def async_service_handler(service): + """Handle for services.""" + entity_ids = service.data.get(ATTR_ENTITY_ID) + if entity_ids: + devices = [device for device in hass.data[DATA_EPSON] + if device.entity_id in entity_ids] + else: + devices = hass.data[DATA_EPSON] + for device in devices: + if service.service == SERVICE_SELECT_CMODE: + cmode = service.data.get(ATTR_CMODE) + await device.select_cmode(cmode) + await device.update() + from epson_projector.const import (CMODE_LIST_SET) + epson_schema = MEDIA_PLAYER_SCHEMA.extend({ + vol.Required(ATTR_CMODE): vol.All(cv.string, vol.Any(*CMODE_LIST_SET)) + }) + hass.services.async_register( + DOMAIN, SERVICE_SELECT_CMODE, async_service_handler, + schema=epson_schema) + + +class EpsonProjector(MediaPlayerDevice): + """Representation of Epson Projector Device.""" + + def __init__(self, websession, name, host, port, encryption): + """Initialize entity to control Epson projector.""" + self._name = name + import epson_projector as epson + from epson_projector.const import DEFAULT_SOURCES + self._projector = epson.Projector( + host, + websession=websession, + port=port) + self._cmode = None + self._source_list = list(DEFAULT_SOURCES.values()) + self._source = None + self._volume = None + self._state = None + + async def update(self): + """Update state of device.""" + from epson_projector.const import ( + EPSON_CODES, POWER, + CMODE, CMODE_LIST, SOURCE, VOLUME, + BUSY, SOURCE_LIST) + is_turned_on = await self._projector.get_property(POWER) + _LOGGER.debug("Project turn on/off status: %s", is_turned_on) + if is_turned_on and is_turned_on == EPSON_CODES[POWER]: + self._state = STATE_ON + cmode = await self._projector.get_property(CMODE) + self._cmode = CMODE_LIST.get(cmode, self._cmode) + source = await self._projector.get_property(SOURCE) + self._source = SOURCE_LIST.get(source, self._source) + volume = await self._projector.get_property(VOLUME) + if volume: + self._volume = volume + elif is_turned_on == BUSY: + self._state = STATE_ON + else: + self._state = STATE_OFF + + @property + def name(self): + """Return the name of the device.""" + return self._name + + @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_EPSON + + async def async_turn_on(self): + """Turn on epson.""" + from epson_projector.const import TURN_ON + await self._projector.send_command(TURN_ON) + + async def async_turn_off(self): + """Turn off epson.""" + from epson_projector.const import TURN_OFF + await self._projector.send_command(TURN_OFF) + + @property + def source_list(self): + """List of available input sources.""" + return self._source_list + + @property + def source(self): + """Get current input sources.""" + return self._source + + @property + def volume_level(self): + """Return the volume level of the media player (0..1).""" + return self._volume + + async def select_cmode(self, cmode): + """Set color mode in Epson.""" + from epson_projector.const import (CMODE_LIST_SET) + await self._projector.send_command(CMODE_LIST_SET[cmode]) + + async def async_select_source(self, source): + """Select input source.""" + from epson_projector.const import INV_SOURCES + selected_source = INV_SOURCES[source] + await self._projector.send_command(selected_source) + + async def async_mute_volume(self, mute): + """Mute (true) or unmute (false) sound.""" + from epson_projector.const import MUTE + await self._projector.send_command(MUTE) + + async def async_volume_up(self): + """Increase volume.""" + from epson_projector.const import VOL_UP + await self._projector.send_command(VOL_UP) + + async def async_volume_down(self): + """Decrease volume.""" + from epson_projector.const import VOL_DOWN + await self._projector.send_command(VOL_DOWN) + + async def async_media_play(self): + """Play media via Epson.""" + from epson_projector.const import PLAY + await self._projector.send_command(PLAY) + + async def async_media_pause(self): + """Pause media via Epson.""" + from epson_projector.const import PAUSE + await self._projector.send_command(PAUSE) + + async def async_media_next_track(self): + """Skip to next.""" + from epson_projector.const import FAST + await self._projector.send_command(FAST) + + async def async_media_previous_track(self): + """Skip to previous.""" + from epson_projector.const import BACK + await self._projector.send_command(BACK) + + @property + def device_state_attributes(self): + """Return device specific state attributes.""" + attributes = {} + if self._cmode is not None: + attributes[ATTR_CMODE] = self._cmode + return attributes diff --git a/homeassistant/components/media_player/services.yaml b/homeassistant/components/media_player/services.yaml index 765f7e1f0f7..3c91f19469b 100644 --- a/homeassistant/components/media_player/services.yaml +++ b/homeassistant/components/media_player/services.yaml @@ -422,3 +422,13 @@ blackbird_set_all_zones: source: description: Name of source to switch to. example: 'Source 1' + +epson_select_cmode: + description: Select Color mode of Epson projector + fields: + entity_id: + description: Name of projector + example: 'media_player.epson_projector' + cmode: + description: Name of Cmode + example: 'cinema' diff --git a/requirements_all.txt b/requirements_all.txt index 3b1096d36eb..6ce31803335 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -294,6 +294,9 @@ enocean==0.40 # homeassistant.components.sensor.season ephem==3.7.6.0 +# homeassistant.components.media_player.epson +epson-projector==0.1.3 + # homeassistant.components.netgear_lte eternalegypt==0.0.1