Add unique_id configuration variable to command_line integration (#58596)
This commit is contained in:
parent
545b10a711
commit
d26275011a
8 changed files with 209 additions and 4 deletions
|
@ -16,6 +16,7 @@ from homeassistant.const import (
|
|||
CONF_NAME,
|
||||
CONF_PAYLOAD_OFF,
|
||||
CONF_PAYLOAD_ON,
|
||||
CONF_UNIQUE_ID,
|
||||
CONF_VALUE_TEMPLATE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -43,6 +44,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
|
||||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -64,6 +66,7 @@ def setup_platform(
|
|||
device_class = config.get(CONF_DEVICE_CLASS)
|
||||
value_template = config.get(CONF_VALUE_TEMPLATE)
|
||||
command_timeout = config.get(CONF_COMMAND_TIMEOUT)
|
||||
unique_id = config.get(CONF_UNIQUE_ID)
|
||||
if value_template is not None:
|
||||
value_template.hass = hass
|
||||
data = CommandSensorData(hass, command, command_timeout)
|
||||
|
@ -71,7 +74,14 @@ def setup_platform(
|
|||
add_entities(
|
||||
[
|
||||
CommandBinarySensor(
|
||||
hass, data, name, device_class, payload_on, payload_off, value_template
|
||||
hass,
|
||||
data,
|
||||
name,
|
||||
device_class,
|
||||
payload_on,
|
||||
payload_off,
|
||||
value_template,
|
||||
unique_id,
|
||||
)
|
||||
],
|
||||
True,
|
||||
|
@ -82,7 +92,15 @@ class CommandBinarySensor(BinarySensorEntity):
|
|||
"""Representation of a command line binary sensor."""
|
||||
|
||||
def __init__(
|
||||
self, hass, data, name, device_class, payload_on, payload_off, value_template
|
||||
self,
|
||||
hass,
|
||||
data,
|
||||
name,
|
||||
device_class,
|
||||
payload_on,
|
||||
payload_off,
|
||||
value_template,
|
||||
unique_id,
|
||||
):
|
||||
"""Initialize the Command line binary sensor."""
|
||||
self._hass = hass
|
||||
|
@ -93,6 +111,7 @@ class CommandBinarySensor(BinarySensorEntity):
|
|||
self._payload_on = payload_on
|
||||
self._payload_off = payload_off
|
||||
self._value_template = value_template
|
||||
self._attr_unique_id = unique_id
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
|
|
@ -13,6 +13,7 @@ from homeassistant.const import (
|
|||
CONF_COMMAND_STOP,
|
||||
CONF_COVERS,
|
||||
CONF_FRIENDLY_NAME,
|
||||
CONF_UNIQUE_ID,
|
||||
CONF_VALUE_TEMPLATE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -35,6 +36,7 @@ COVER_SCHEMA = vol.Schema(
|
|||
vol.Optional(CONF_FRIENDLY_NAME): cv.string,
|
||||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -71,6 +73,7 @@ def setup_platform(
|
|||
device_config.get(CONF_COMMAND_STATE),
|
||||
value_template,
|
||||
device_config[CONF_COMMAND_TIMEOUT],
|
||||
device_config.get(CONF_UNIQUE_ID),
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -94,6 +97,7 @@ class CommandCover(CoverEntity):
|
|||
command_state,
|
||||
value_template,
|
||||
timeout,
|
||||
unique_id,
|
||||
):
|
||||
"""Initialize the cover."""
|
||||
self._hass = hass
|
||||
|
@ -105,6 +109,7 @@ class CommandCover(CoverEntity):
|
|||
self._command_state = command_state
|
||||
self._value_template = value_template
|
||||
self._timeout = timeout
|
||||
self._attr_unique_id = unique_id
|
||||
|
||||
def _move_cover(self, command):
|
||||
"""Execute the actual commands."""
|
||||
|
|
|
@ -12,6 +12,7 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
|||
from homeassistant.const import (
|
||||
CONF_COMMAND,
|
||||
CONF_NAME,
|
||||
CONF_UNIQUE_ID,
|
||||
CONF_UNIT_OF_MEASUREMENT,
|
||||
CONF_VALUE_TEMPLATE,
|
||||
STATE_UNKNOWN,
|
||||
|
@ -43,6 +44,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
|
||||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -62,13 +64,19 @@ def setup_platform(
|
|||
unit = config.get(CONF_UNIT_OF_MEASUREMENT)
|
||||
value_template = config.get(CONF_VALUE_TEMPLATE)
|
||||
command_timeout = config.get(CONF_COMMAND_TIMEOUT)
|
||||
unique_id = config.get(CONF_UNIQUE_ID)
|
||||
if value_template is not None:
|
||||
value_template.hass = hass
|
||||
json_attributes = config.get(CONF_JSON_ATTRIBUTES)
|
||||
data = CommandSensorData(hass, command, command_timeout)
|
||||
|
||||
add_entities(
|
||||
[CommandSensor(hass, data, name, unit, value_template, json_attributes)], True
|
||||
[
|
||||
CommandSensor(
|
||||
hass, data, name, unit, value_template, json_attributes, unique_id
|
||||
)
|
||||
],
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
|
@ -76,7 +84,14 @@ class CommandSensor(SensorEntity):
|
|||
"""Representation of a sensor that is using shell commands."""
|
||||
|
||||
def __init__(
|
||||
self, hass, data, name, unit_of_measurement, value_template, json_attributes
|
||||
self,
|
||||
hass,
|
||||
data,
|
||||
name,
|
||||
unit_of_measurement,
|
||||
value_template,
|
||||
json_attributes,
|
||||
unique_id,
|
||||
):
|
||||
"""Initialize the sensor."""
|
||||
self._hass = hass
|
||||
|
@ -87,6 +102,7 @@ class CommandSensor(SensorEntity):
|
|||
self._state = None
|
||||
self._unit_of_measurement = unit_of_measurement
|
||||
self._value_template = value_template
|
||||
self._attr_unique_id = unique_id
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
|
|
@ -17,6 +17,7 @@ from homeassistant.const import (
|
|||
CONF_FRIENDLY_NAME,
|
||||
CONF_ICON_TEMPLATE,
|
||||
CONF_SWITCHES,
|
||||
CONF_UNIQUE_ID,
|
||||
CONF_VALUE_TEMPLATE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -39,6 +40,7 @@ SWITCH_SCHEMA = vol.Schema(
|
|||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_ICON_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -81,6 +83,7 @@ def setup_platform(
|
|||
icon_template,
|
||||
value_template,
|
||||
device_config[CONF_COMMAND_TIMEOUT],
|
||||
device_config.get(CONF_UNIQUE_ID),
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -105,6 +108,7 @@ class CommandSwitch(SwitchEntity):
|
|||
icon_template,
|
||||
value_template,
|
||||
timeout,
|
||||
unique_id,
|
||||
):
|
||||
"""Initialize the switch."""
|
||||
self._hass = hass
|
||||
|
@ -117,6 +121,7 @@ class CommandSwitch(SwitchEntity):
|
|||
self._icon_template = icon_template
|
||||
self._value_template = value_template
|
||||
self._timeout = timeout
|
||||
self._attr_unique_id = unique_id
|
||||
|
||||
def _switch(self, command):
|
||||
"""Execute the actual commands."""
|
||||
|
|
|
@ -7,6 +7,7 @@ from homeassistant import setup
|
|||
from homeassistant.components.binary_sensor import DOMAIN
|
||||
from homeassistant.const import STATE_OFF, STATE_ON
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry
|
||||
|
||||
|
||||
async def setup_test_entity(hass: HomeAssistant, config_dict: dict[str, Any]) -> None:
|
||||
|
@ -65,3 +66,47 @@ async def test_sensor_off(hass: HomeAssistant) -> None:
|
|||
)
|
||||
entity_state = hass.states.get("binary_sensor.test")
|
||||
assert entity_state.state == STATE_OFF
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique_id option and if it only creates one binary sensor per id."""
|
||||
assert await setup.async_setup_component(
|
||||
hass,
|
||||
DOMAIN,
|
||||
{
|
||||
DOMAIN: [
|
||||
{
|
||||
"platform": "command_line",
|
||||
"unique_id": "unique",
|
||||
"command": "echo 0",
|
||||
},
|
||||
{
|
||||
"platform": "command_line",
|
||||
"unique_id": "not-so-unique-anymore",
|
||||
"command": "echo 1",
|
||||
},
|
||||
{
|
||||
"platform": "command_line",
|
||||
"unique_id": "not-so-unique-anymore",
|
||||
"command": "echo 2",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(hass.states.async_all()) == 2
|
||||
|
||||
ent_reg = entity_registry.async_get(hass)
|
||||
|
||||
assert len(ent_reg.entities) == 2
|
||||
assert (
|
||||
ent_reg.async_get_entity_id("binary_sensor", "command_line", "unique")
|
||||
is not None
|
||||
)
|
||||
assert (
|
||||
ent_reg.async_get_entity_id(
|
||||
"binary_sensor", "command_line", "not-so-unique-anymore"
|
||||
)
|
||||
is not None
|
||||
)
|
||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.const import (
|
|||
SERVICE_STOP_COVER,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import async_fire_time_changed, get_fixture_path
|
||||
|
@ -160,3 +161,41 @@ async def test_move_cover_failure(caplog: Any, hass: HomeAssistant) -> None:
|
|||
DOMAIN, SERVICE_OPEN_COVER, {ATTR_ENTITY_ID: "cover.test"}, blocking=True
|
||||
)
|
||||
assert "Command failed" in caplog.text
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique_id option and if it only creates one cover per id."""
|
||||
await setup_test_entity(
|
||||
hass,
|
||||
{
|
||||
"unique": {
|
||||
"command_open": "echo open",
|
||||
"command_close": "echo close",
|
||||
"command_stop": "echo stop",
|
||||
"unique_id": "unique",
|
||||
},
|
||||
"not_unique_1": {
|
||||
"command_open": "echo open",
|
||||
"command_close": "echo close",
|
||||
"command_stop": "echo stop",
|
||||
"unique_id": "not-so-unique-anymore",
|
||||
},
|
||||
"not_unique_2": {
|
||||
"command_open": "echo open",
|
||||
"command_close": "echo close",
|
||||
"command_stop": "echo stop",
|
||||
"unique_id": "not-so-unique-anymore",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 2
|
||||
|
||||
ent_reg = entity_registry.async_get(hass)
|
||||
|
||||
assert len(ent_reg.entities) == 2
|
||||
assert ent_reg.async_get_entity_id("cover", "command_line", "unique") is not None
|
||||
assert (
|
||||
ent_reg.async_get_entity_id("cover", "command_line", "not-so-unique-anymore")
|
||||
is not None
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@ from unittest.mock import patch
|
|||
from homeassistant import setup
|
||||
from homeassistant.components.sensor import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry
|
||||
|
||||
|
||||
async def setup_test_entities(hass: HomeAssistant, config_dict: dict[str, Any]) -> None:
|
||||
|
@ -223,3 +224,42 @@ async def test_update_with_unnecessary_json_attrs(caplog, hass: HomeAssistant) -
|
|||
assert entity_state.attributes["key"] == "some_json_value"
|
||||
assert entity_state.attributes["another_key"] == "another_json_value"
|
||||
assert "key_three" not in entity_state.attributes
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique_id option and if it only creates one sensor per id."""
|
||||
assert await setup.async_setup_component(
|
||||
hass,
|
||||
DOMAIN,
|
||||
{
|
||||
DOMAIN: [
|
||||
{
|
||||
"platform": "command_line",
|
||||
"unique_id": "unique",
|
||||
"command": "echo 0",
|
||||
},
|
||||
{
|
||||
"platform": "command_line",
|
||||
"unique_id": "not-so-unique-anymore",
|
||||
"command": "echo 1",
|
||||
},
|
||||
{
|
||||
"platform": "command_line",
|
||||
"unique_id": "not-so-unique-anymore",
|
||||
"command": "echo 2",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(hass.states.async_all()) == 2
|
||||
|
||||
ent_reg = entity_registry.async_get(hass)
|
||||
|
||||
assert len(ent_reg.entities) == 2
|
||||
assert ent_reg.async_get_entity_id("sensor", "command_line", "unique") is not None
|
||||
assert (
|
||||
ent_reg.async_get_entity_id("sensor", "command_line", "not-so-unique-anymore")
|
||||
is not None
|
||||
)
|
||||
|
|
|
@ -18,6 +18,7 @@ from homeassistant.const import (
|
|||
STATE_ON,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
@ -376,3 +377,38 @@ async def test_no_switches(caplog: Any, hass: HomeAssistant) -> None:
|
|||
|
||||
await setup_test_entity(hass, {})
|
||||
assert "No switches" in caplog.text
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique_id option and if it only creates one switch per id."""
|
||||
await setup_test_entity(
|
||||
hass,
|
||||
{
|
||||
"unique": {
|
||||
"command_on": "echo on",
|
||||
"command_off": "echo off",
|
||||
"unique_id": "unique",
|
||||
},
|
||||
"not_unique_1": {
|
||||
"command_on": "echo on",
|
||||
"command_off": "echo off",
|
||||
"unique_id": "not-so-unique-anymore",
|
||||
},
|
||||
"not_unique_2": {
|
||||
"command_on": "echo on",
|
||||
"command_off": "echo off",
|
||||
"unique_id": "not-so-unique-anymore",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 2
|
||||
|
||||
ent_reg = entity_registry.async_get(hass)
|
||||
|
||||
assert len(ent_reg.entities) == 2
|
||||
assert ent_reg.async_get_entity_id("switch", "command_line", "unique") is not None
|
||||
assert (
|
||||
ent_reg.async_get_entity_id("switch", "command_line", "not-so-unique-anymore")
|
||||
is not None
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue