mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Add transition to LiteJet (#47657)
This commit is contained in:
parent
0f78004ede
commit
72a3860361
@ -10,13 +10,44 @@ import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.const import CONF_PORT
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import CONF_DEFAULT_TRANSITION, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LiteJetOptionsFlow(config_entries.OptionsFlow):
|
||||
"""Handle LiteJet options."""
|
||||
|
||||
def __init__(self, config_entry):
|
||||
"""Initialize LiteJet options flow."""
|
||||
self.config_entry = config_entry
|
||||
|
||||
async def async_step_init(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> dict[str, Any]:
|
||||
"""Manage LiteJet options."""
|
||||
if user_input is not None:
|
||||
return self.async_create_entry(title="", data=user_input)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="init",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_DEFAULT_TRANSITION,
|
||||
default=self.config_entry.options.get(
|
||||
CONF_DEFAULT_TRANSITION, 0
|
||||
),
|
||||
): cv.positive_int,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class LiteJetConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""LiteJet config flow."""
|
||||
|
||||
@ -54,3 +85,9 @@ class LiteJetConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
async def async_step_import(self, import_data):
|
||||
"""Import litejet config from configuration.yaml."""
|
||||
return self.async_create_entry(title=import_data[CONF_PORT], data=import_data)
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(config_entry):
|
||||
"""Get the options flow for this handler."""
|
||||
return LiteJetOptionsFlow(config_entry)
|
||||
|
@ -6,3 +6,5 @@ CONF_EXCLUDE_NAMES = "exclude_names"
|
||||
CONF_INCLUDE_SWITCHES = "include_switches"
|
||||
|
||||
PLATFORMS = ["light", "switch", "scene"]
|
||||
|
||||
CONF_DEFAULT_TRANSITION = "default_transition"
|
||||
|
@ -3,11 +3,13 @@ import logging
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
ATTR_TRANSITION,
|
||||
SUPPORT_BRIGHTNESS,
|
||||
SUPPORT_TRANSITION,
|
||||
LightEntity,
|
||||
)
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import CONF_DEFAULT_TRANSITION, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -23,7 +25,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
entities = []
|
||||
for i in system.loads():
|
||||
name = system.get_load_name(i)
|
||||
entities.append(LiteJetLight(config_entry.entry_id, system, i, name))
|
||||
entities.append(LiteJetLight(config_entry, system, i, name))
|
||||
return entities
|
||||
|
||||
async_add_entities(await hass.async_add_executor_job(get_entities, system), True)
|
||||
@ -32,9 +34,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
class LiteJetLight(LightEntity):
|
||||
"""Representation of a single LiteJet light."""
|
||||
|
||||
def __init__(self, entry_id, lj, i, name):
|
||||
def __init__(self, config_entry, lj, i, name):
|
||||
"""Initialize a LiteJet light."""
|
||||
self._entry_id = entry_id
|
||||
self._config_entry = config_entry
|
||||
self._lj = lj
|
||||
self._index = i
|
||||
self._brightness = 0
|
||||
@ -57,7 +59,7 @@ class LiteJetLight(LightEntity):
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Flag supported features."""
|
||||
return SUPPORT_BRIGHTNESS
|
||||
return SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@ -67,7 +69,7 @@ class LiteJetLight(LightEntity):
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique identifier for this light."""
|
||||
return f"{self._entry_id}_{self._index}"
|
||||
return f"{self._config_entry.entry_id}_{self._index}"
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
@ -91,16 +93,33 @@ class LiteJetLight(LightEntity):
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn on the light."""
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
brightness = int(kwargs[ATTR_BRIGHTNESS] / 255 * 99)
|
||||
self._lj.activate_load_at(self._index, brightness, 0)
|
||||
else:
|
||||
|
||||
# If neither attribute is specified then the simple activate load
|
||||
# LiteJet API will use the per-light default brightness and
|
||||
# transition values programmed in the LiteJet system.
|
||||
if ATTR_BRIGHTNESS not in kwargs and ATTR_TRANSITION not in kwargs:
|
||||
self._lj.activate_load(self._index)
|
||||
return
|
||||
|
||||
# If either attribute is specified then Home Assistant must
|
||||
# control both values.
|
||||
default_transition = self._config_entry.options.get(CONF_DEFAULT_TRANSITION, 0)
|
||||
transition = kwargs.get(ATTR_TRANSITION, default_transition)
|
||||
brightness = int(kwargs.get(ATTR_BRIGHTNESS, 255) / 255 * 99)
|
||||
|
||||
self._lj.activate_load_at(self._index, brightness, int(transition))
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn off the light."""
|
||||
if ATTR_TRANSITION in kwargs:
|
||||
self._lj.activate_load_at(self._index, 0, kwargs[ATTR_TRANSITION])
|
||||
return
|
||||
|
||||
# If transition attribute is not specified then the simple
|
||||
# deactivate load LiteJet API will use the per-light default
|
||||
# transition value programmed in the LiteJet system.
|
||||
self._lj.deactivate_load(self._index)
|
||||
|
||||
def update(self):
|
||||
"""Retrieve the light's brightness from the LiteJet system."""
|
||||
self._brightness = self._lj.get_load_level(self._index) / 99 * 255
|
||||
self._brightness = int(self._lj.get_load_level(self._index) / 99 * 255)
|
||||
|
@ -15,5 +15,15 @@
|
||||
"error": {
|
||||
"open_failed": "Cannot open the specified serial port."
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "Configure LiteJet",
|
||||
"data": {
|
||||
"default_transition": "Default Transition (seconds)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -15,5 +15,15 @@
|
||||
"title": "Connect To LiteJet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"data": {
|
||||
"default_transition": "Default Transition (seconds)"
|
||||
},
|
||||
"title": "Configure LiteJet"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ from unittest.mock import patch
|
||||
|
||||
from serial import SerialException
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.litejet.const import DOMAIN
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components.litejet.const import CONF_DEFAULT_TRANSITION, DOMAIN
|
||||
from homeassistant.const import CONF_PORT
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
@ -76,3 +76,22 @@ async def test_import_step(hass):
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == test_data[CONF_PORT]
|
||||
assert result["data"] == test_data
|
||||
|
||||
|
||||
async def test_options(hass):
|
||||
"""Test updating options."""
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={CONF_PORT: "/dev/test"})
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_DEFAULT_TRANSITION: 12},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["data"] == {CONF_DEFAULT_TRANSITION: 12}
|
||||
|
@ -2,7 +2,8 @@
|
||||
import logging
|
||||
|
||||
from homeassistant.components import light
|
||||
from homeassistant.components.light import ATTR_BRIGHTNESS
|
||||
from homeassistant.components.light import ATTR_BRIGHTNESS, ATTR_TRANSITION
|
||||
from homeassistant.components.litejet.const import CONF_DEFAULT_TRANSITION
|
||||
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON
|
||||
|
||||
from . import async_init_integration
|
||||
@ -33,6 +34,55 @@ async def test_on_brightness(hass, mock_litejet):
|
||||
mock_litejet.activate_load_at.assert_called_with(ENTITY_LIGHT_NUMBER, 39, 0)
|
||||
|
||||
|
||||
async def test_default_transition(hass, mock_litejet):
|
||||
"""Test turning the light on with the default transition option."""
|
||||
entry = await async_init_integration(hass)
|
||||
|
||||
hass.config_entries.async_update_entry(entry, options={CONF_DEFAULT_TRANSITION: 12})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(ENTITY_LIGHT).state == "off"
|
||||
assert hass.states.get(ENTITY_OTHER_LIGHT).state == "off"
|
||||
|
||||
assert not light.is_on(hass, ENTITY_LIGHT)
|
||||
|
||||
await hass.services.async_call(
|
||||
light.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_BRIGHTNESS: 102},
|
||||
blocking=True,
|
||||
)
|
||||
mock_litejet.activate_load_at.assert_called_with(ENTITY_LIGHT_NUMBER, 39, 12)
|
||||
|
||||
|
||||
async def test_transition(hass, mock_litejet):
|
||||
"""Test turning the light on with transition."""
|
||||
await async_init_integration(hass)
|
||||
|
||||
assert hass.states.get(ENTITY_LIGHT).state == "off"
|
||||
assert hass.states.get(ENTITY_OTHER_LIGHT).state == "off"
|
||||
|
||||
assert not light.is_on(hass, ENTITY_LIGHT)
|
||||
|
||||
# On
|
||||
await hass.services.async_call(
|
||||
light.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_TRANSITION: 5},
|
||||
blocking=True,
|
||||
)
|
||||
mock_litejet.activate_load_at.assert_called_with(ENTITY_LIGHT_NUMBER, 99, 5)
|
||||
|
||||
# Off
|
||||
await hass.services.async_call(
|
||||
light.DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_TRANSITION: 5},
|
||||
blocking=True,
|
||||
)
|
||||
mock_litejet.activate_load_at.assert_called_with(ENTITY_LIGHT_NUMBER, 0, 5)
|
||||
|
||||
|
||||
async def test_on_off(hass, mock_litejet):
|
||||
"""Test turning the light on and off."""
|
||||
await async_init_integration(hass)
|
||||
@ -91,9 +141,7 @@ async def test_activated_event(hass, mock_litejet):
|
||||
assert light.is_on(hass, ENTITY_OTHER_LIGHT)
|
||||
assert hass.states.get(ENTITY_LIGHT).state == "on"
|
||||
assert hass.states.get(ENTITY_OTHER_LIGHT).state == "on"
|
||||
assert (
|
||||
int(hass.states.get(ENTITY_OTHER_LIGHT).attributes.get(ATTR_BRIGHTNESS)) == 103
|
||||
)
|
||||
assert hass.states.get(ENTITY_OTHER_LIGHT).attributes.get(ATTR_BRIGHTNESS) == 103
|
||||
|
||||
|
||||
async def test_deactivated_event(hass, mock_litejet):
|
||||
|
Loading…
x
Reference in New Issue
Block a user