Fix template light returning NULL in color or temperature (#33498)

* Support for returning NULL in color or temperature. Fixes #33469

* Added further support for ‘None’ returns in level template

* Removed assumption that template render may not be a string

* Streamlined code per cloud pylint

* Updates per code review suggestions

* Added improved error handling and logging for brightness

* Additional exception handling for temperature
This commit is contained in:
Alistair Galbraith 2020-04-02 15:41:19 -07:00 committed by GitHub
parent 8fbdc703e0
commit 3db9d6a6aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 10 deletions

View File

@ -378,6 +378,9 @@ class LightTemplate(Light):
return
try:
brightness = self._level_template.async_render()
if brightness in ("None", ""):
self._brightness = None
return
if 0 <= int(brightness) <= 255:
self._brightness = int(brightness)
else:
@ -385,9 +388,15 @@ class LightTemplate(Light):
"Received invalid brightness : %s. Expected: 0-255", brightness
)
self._brightness = None
except TemplateError as ex:
_LOGGER.error(ex)
self._state = None
except ValueError:
_LOGGER.error(
"Template must supply an integer brightness from 0-255, or 'None'",
exc_info=True,
)
self._brightness = None
except TemplateError:
_LOGGER.error("Invalid template", exc_info=True)
self._brightness = None
@callback
def update_state(self):
@ -415,7 +424,11 @@ class LightTemplate(Light):
if self._temperature_template is None:
return
try:
temperature = int(self._temperature_template.async_render())
render = self._temperature_template.async_render()
if render in ("None", ""):
self._temperature = None
return
temperature = int(render)
if self.min_mireds <= temperature <= self.max_mireds:
self._temperature = temperature
else:
@ -425,6 +438,12 @@ class LightTemplate(Light):
self.max_mireds,
)
self._temperature = None
except ValueError:
_LOGGER.error(
"Template must supply an integer temperature within the range for this light, or 'None'",
exc_info=True,
)
self._temperature = None
except TemplateError:
_LOGGER.error("Cannot evaluate temperature template", exc_info=True)
self._temperature = None
@ -435,10 +454,11 @@ class LightTemplate(Light):
if self._color_template is None:
return
self._color = None
try:
render = self._color_template.async_render()
if render in ("None", ""):
self._color = None
return
h_str, s_str = map(
float, render.replace("(", "").replace(")", "").split(",", 1)
)
@ -455,7 +475,10 @@ class LightTemplate(Light):
h_str,
s_str,
)
self._color = None
else:
_LOGGER.error("Received invalid hs_color : (%s)", render)
except TemplateError as ex:
_LOGGER.error(ex)
self._color = None
except TemplateError:
_LOGGER.error("Cannot evaluate hs_color template", exc_info=True)
self._color = None

View File

@ -543,7 +543,13 @@ class TestTemplateLight:
@pytest.mark.parametrize(
"expected_level,template",
[(255, "{{255}}"), (None, "{{256}}"), (None, "{{x - 12}}")],
[
(255, "{{255}}"),
(None, "{{256}}"),
(None, "{{x - 12}}"),
(None, "{{ none }}"),
(None, ""),
],
)
def test_level_template(self, expected_level, template):
"""Test the template for the level."""
@ -588,7 +594,14 @@ class TestTemplateLight:
@pytest.mark.parametrize(
"expected_temp,template",
[(500, "{{500}}"), (None, "{{501}}"), (None, "{{x - 12}}")],
[
(500, "{{500}}"),
(None, "{{501}}"),
(None, "{{x - 12}}"),
(None, "None"),
(None, "{{ none }}"),
(None, ""),
],
)
def test_temperature_template(self, expected_temp, template):
"""Test the template for the temperature."""
@ -894,6 +907,8 @@ class TestTemplateLight:
(None, "{{(361, 100)}}"),
(None, "{{(360, 101)}}"),
(None, "{{x - 12}}"),
(None, ""),
(None, "{{ none }}"),
],
)
def test_color_template(self, expected_hs, template):