Hyperion: Add brightness, HDMI and effect support (#11543)

* Hyperion: Add brightness, HDMI and effect support

- added brightness support to dim the hyperion light
- changed the "OFF" command to set the color to [0,0,0] after clearing all priorities.
  This is neccesary to keep the light turned off when an HDMI grabber is used for ambilight with hyperion.
- added HDMI ambilight mode recognition and control.
  by setting the "hdmi_priority" in your "configuration.yaml" file (defaults to 880), home assistant will now be able to recognize when the hyperion light is in HDMI ambilight mode and will change its icon to an HDMI symbol and set the status to ON.
Switching the hyperion light to HDMI ambilight mode can be done through the effect option (clears all priorities such that the HDMI grabber remains).
- added effect support for the default effects of hyperion, a custom list can be defined in the "configuration.yaml" file by using the "effect_list" option.

* Hyperion: Add brightness, HDMI and effect support

- added brightness support to dim the hyperion light
- changed the "OFF" command to set the color to [0,0,0] after clearing all priorities.
  This is neccesary to keep the light turned off when an HDMI grabber is used for ambilight with hyperion.
- added HDMI ambilight mode recognition and control.
  by setting the "hdmi_priority" in your "configuration.yaml" file (defaults to 880), home assistant will now be able to recognize when the hyperion light is in HDMI ambilight mode and will change its icon to an HDMI symbol and set the status to ON.
Switching the hyperion light to HDMI ambilight mode can be done through the effect option (clears all priorities such that the HDMI grabber remains).
- added effect support for the default effects of hyperion, a custom list can be defined in the "configuration.yaml" file by using the "effect_list" option.
- fixed some style issues with too long lines

* Hyperion: Add brightness, HDMI and effect support 

 - fixed some more indentation style issues

* Hyperion: Add brightness, HDMI and effect support 

- yet more fixed visuel indent issues

* Hyperion: Add brightness, HDMI and effect support 

- more visuel indents

* Hyperion: Add brightness, HDMI and effect support

- fixed invalid variable "A"

* Hyperion: Add brightness, HDMI and effect support

- remove unnececary brackets
- specify specific exceptions

* correct changing state holding attributes during a service method

Proccesed the comments of @MartinHjelmare: https://github.com/home-assistant/home-assistant/pull/11543#pullrequestreview-88328659

* indent correction

corrected tab instead of 4 spaces

* Hyperion: Add brightness, HDMI and effect support 

- changed 'none' to None
- renamed "self._skip_check" to "self._skip_update"

* Add brightness, HDMI and effect support 

changed checking if a list is empty from "list == []" to "not list"
pull/11634/head
starkillerOG 2018-01-13 21:06:34 +01:00 committed by Martin Hjelmare
parent 5def6ebc3b
commit cdbf2f9293
1 changed files with 130 additions and 11 deletions

View File

@ -11,7 +11,8 @@ import socket
import voluptuous as vol
from homeassistant.components.light import (
ATTR_RGB_COLOR, SUPPORT_RGB_COLOR, Light, PLATFORM_SCHEMA)
ATTR_BRIGHTNESS, ATTR_RGB_COLOR, ATTR_EFFECT, SUPPORT_BRIGHTNESS,
SUPPORT_RGB_COLOR, SUPPORT_EFFECT, Light, PLATFORM_SCHEMA)
from homeassistant.const import (CONF_HOST, CONF_PORT, CONF_NAME)
import homeassistant.helpers.config_validation as cv
@ -19,13 +20,27 @@ _LOGGER = logging.getLogger(__name__)
CONF_DEFAULT_COLOR = 'default_color'
CONF_PRIORITY = 'priority'
CONF_HDMI_PRIORITY = 'hdmi_priority'
CONF_EFFECT_LIST = 'effect_list'
DEFAULT_COLOR = [255, 255, 255]
DEFAULT_NAME = 'Hyperion'
DEFAULT_PORT = 19444
DEFAULT_PRIORITY = 128
DEFAULT_HDMI_PRIORITY = 880
DEFAULT_EFFECT_LIST = ['HDMI', 'Cinema brighten lights', 'Cinema dim lights',
'Knight rider', 'Blue mood blobs', 'Cold mood blobs',
'Full color mood blobs', 'Green mood blobs',
'Red mood blobs', 'Warm mood blobs',
'Police Lights Single', 'Police Lights Solid',
'Rainbow mood', 'Rainbow swirl fast',
'Rainbow swirl', 'Random', 'Running dots',
'System Shutdown', 'Snake', 'Sparks Color', 'Sparks',
'Strobe blue', 'Strobe Raspbmc', 'Strobe white',
'Color traces', 'UDP multicast listener',
'UDP listener', 'X-Mas']
SUPPORT_HYPERION = SUPPORT_RGB_COLOR
SUPPORT_HYPERION = (SUPPORT_RGB_COLOR | SUPPORT_BRIGHTNESS | SUPPORT_EFFECT)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
@ -35,6 +50,11 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
[vol.All(vol.Coerce(int), vol.Range(min=0, max=255))]),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PRIORITY, default=DEFAULT_PRIORITY): cv.positive_int,
vol.Optional(CONF_HDMI_PRIORITY,
default=DEFAULT_HDMI_PRIORITY): cv.positive_int,
vol.Optional(CONF_EFFECT_LIST,
default=DEFAULT_EFFECT_LIST): vol.All(cv.ensure_list,
[cv.string]),
})
@ -43,10 +63,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
priority = config.get(CONF_PRIORITY)
hdmi_priority = config.get(CONF_HDMI_PRIORITY)
default_color = config.get(CONF_DEFAULT_COLOR)
effect_list = config.get(CONF_EFFECT_LIST)
device = Hyperion(config.get(CONF_NAME), host, port, priority,
default_color)
default_color, hdmi_priority, effect_list)
if device.setup():
add_devices([device])
@ -57,20 +79,33 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class Hyperion(Light):
"""Representation of a Hyperion remote."""
def __init__(self, name, host, port, priority, default_color):
def __init__(self, name, host, port, priority, default_color,
hdmi_priority, effect_list):
"""Initialize the light."""
self._host = host
self._port = port
self._name = name
self._priority = priority
self._hdmi_priority = hdmi_priority
self._default_color = default_color
self._rgb_color = [0, 0, 0]
self._rgb_mem = [0, 0, 0]
self._brightness = 255
self._icon = 'mdi:lightbulb'
self._effect_list = effect_list
self._effect = None
self._skip_update = False
@property
def name(self):
"""Return the name of the light."""
return self._name
@property
def brightness(self):
"""Return the brightness of this light between 0..255."""
return self._brightness
@property
def rgb_color(self):
"""Return last RGB color value set."""
@ -81,6 +116,21 @@ class Hyperion(Light):
"""Return true if not black."""
return self._rgb_color != [0, 0, 0]
@property
def icon(self):
"""Return state specific icon."""
return self._icon
@property
def effect(self):
"""Return the current effect."""
return self._effect
@property
def effect_list(self):
"""Return the list of supported effects."""
return self._effect_list
@property
def supported_features(self):
"""Flag supported features."""
@ -89,35 +139,104 @@ class Hyperion(Light):
def turn_on(self, **kwargs):
"""Turn the lights on."""
if ATTR_RGB_COLOR in kwargs:
self._rgb_color = kwargs[ATTR_RGB_COLOR]
rgb_color = kwargs[ATTR_RGB_COLOR]
elif self._rgb_mem == [0, 0, 0]:
rgb_color = self._default_color
else:
self._rgb_color = self._default_color
rgb_color = self._rgb_mem
if ATTR_BRIGHTNESS in kwargs:
brightness = kwargs[ATTR_BRIGHTNESS]
if ATTR_EFFECT in kwargs:
self._skip_update = True
self._effect = kwargs[ATTR_EFFECT]
if self._effect == 'HDMI':
self.json_request({'command': 'clearall'})
self._icon = 'mdi:video-input-hdmi'
self._brightness = 255
self._rgb_color = [125, 125, 125]
else:
self.json_request({
'command': 'effect',
'priority': self._priority,
'effect': {'name': self._effect}
})
self._icon = 'mdi:lava-lamp'
self._rgb_color = [175, 0, 255]
return
cal_color = [int(round(x*float(brightness)/255))
for x in rgb_color]
self.json_request({
'command': 'color',
'priority': self._priority,
'color': self._rgb_color
'color': cal_color
})
def turn_off(self, **kwargs):
"""Disconnect all remotes."""
self.json_request({'command': 'clearall'})
self._rgb_color = [0, 0, 0]
self.json_request({
'command': 'color',
'priority': self._priority,
'color': [0, 0, 0]
})
def update(self):
"""Get the remote's active color."""
"""Get the lights status."""
# postpone the immediate state check for changes that take time
if self._skip_update:
self._skip_update = False
return
response = self.json_request({'command': 'serverinfo'})
if response:
# workaround for outdated Hyperion
if 'activeLedColor' not in response['info']:
self._rgb_color = self._default_color
self._rgb_mem = self._default_color
self._brightness = 255
self._icon = 'mdi:lightbulb'
self._effect = None
return
# Check if Hyperion is in ambilight mode trough an HDMI grabber
try:
active_priority = response['info']['priorities'][0]['priority']
if active_priority == self._hdmi_priority:
self._brightness = 255
self._rgb_color = [125, 125, 125]
self._icon = 'mdi:video-input-hdmi'
self._effect = 'HDMI'
return
except (KeyError, IndexError):
pass
if response['info']['activeLedColor'] == []:
self._rgb_color = [0, 0, 0]
if not response['info']['activeLedColor']:
# Get the active effect
if response['info']['activeEffects']:
self._rgb_color = [175, 0, 255]
self._icon = 'mdi:lava-lamp'
try:
s_name = response['info']['activeEffects'][0]["script"]
s_name = s_name.split('/')[-1][:-3].split("-")[0]
self._effect = [x for x in self._effect_list
if s_name.lower() in x.lower()][0]
except (KeyError, IndexError):
self._effect = None
# Bulb off state
else:
self._rgb_color = [0, 0, 0]
self._icon = 'mdi:lightbulb'
self._effect = None
else:
# Get the RGB color
self._rgb_color =\
response['info']['activeLedColor'][0]['RGB Value']
self._brightness = max(self._rgb_color)
self._rgb_mem = [int(round(float(x)*255/self._brightness))
for x in self._rgb_color]
self._icon = 'mdi:lightbulb'
self._effect = None
def setup(self):
"""Get the hostname of the remote."""