Fix manual update for Command Line (#94433)

Manual update command line
This commit is contained in:
G Johansson 2023-06-12 21:50:23 +02:00 committed by GitHub
parent af6dac8584
commit f931cc3d1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 263 additions and 3 deletions

View File

@ -31,6 +31,7 @@ from homeassistant.helpers.issue_registry import IssueSeverity, async_create_iss
from homeassistant.helpers.template import Template
from homeassistant.helpers.template_entity import ManualTriggerEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import dt as dt_util
from .const import CONF_COMMAND_TIMEOUT, DEFAULT_TIMEOUT, DOMAIN, LOGGER
from .sensor import CommandSensorData
@ -185,3 +186,10 @@ class CommandBinarySensor(ManualTriggerEntity, BinarySensorEntity):
self._process_manual_data(value)
self.async_write_ha_state()
async def async_update(self) -> None:
"""Update the entity.
Only used by the generic entity update service.
"""
await self._update_entity_state(dt_util.now())

View File

@ -32,7 +32,7 @@ from homeassistant.helpers.issue_registry import IssueSeverity, async_create_iss
from homeassistant.helpers.template import Template
from homeassistant.helpers.template_entity import ManualTriggerEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import slugify
from homeassistant.util import dt as dt_util, slugify
from .const import CONF_COMMAND_TIMEOUT, DEFAULT_TIMEOUT, DOMAIN, LOGGER
from .utils import call_shell_with_timeout, check_output_or_log
@ -224,6 +224,13 @@ class CommandCover(ManualTriggerEntity, CoverEntity):
self._process_manual_data(payload)
await self.async_update_ha_state(True)
async def async_update(self) -> None:
"""Update the entity.
Only used by the generic entity update service.
"""
await self._update_entity_state(dt_util.now())
async def async_open_cover(self, **kwargs: Any) -> None:
"""Open the cover."""
await self.hass.async_add_executor_job(self._move_cover, self._command_open)

View File

@ -36,6 +36,7 @@ from homeassistant.helpers.issue_registry import IssueSeverity, async_create_iss
from homeassistant.helpers.template import Template
from homeassistant.helpers.template_entity import ManualTriggerEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import dt as dt_util
from .const import CONF_COMMAND_TIMEOUT, DEFAULT_TIMEOUT, DOMAIN, LOGGER
from .utils import check_output_or_log
@ -216,6 +217,13 @@ class CommandSensor(ManualTriggerEntity, SensorEntity):
self._process_manual_data(value)
self.async_write_ha_state()
async def async_update(self) -> None:
"""Update the entity.
Only used by the generic entity update service.
"""
await self._update_entity_state(dt_util.now())
class CommandSensorData:
"""The class for handling the data retrieval."""

View File

@ -34,7 +34,7 @@ from homeassistant.helpers.issue_registry import IssueSeverity, async_create_iss
from homeassistant.helpers.template import Template
from homeassistant.helpers.template_entity import ManualTriggerEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import slugify
from homeassistant.util import dt as dt_util, slugify
from .const import CONF_COMMAND_TIMEOUT, DEFAULT_TIMEOUT, DOMAIN, LOGGER
from .utils import call_shell_with_timeout, check_output_or_log
@ -240,6 +240,13 @@ class CommandSwitch(ManualTriggerEntity, SwitchEntity):
self._process_manual_data(payload)
await self.async_update_ha_state(True)
async def async_update(self) -> None:
"""Update the entity.
Only used by the generic entity update service.
"""
await self._update_entity_state(dt_util.now())
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the device on."""
if await self._switch(self._command_on) and not self._command_state:

View File

@ -12,7 +12,11 @@ from homeassistant import setup
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.command_line.binary_sensor import CommandBinarySensor
from homeassistant.components.command_line.const import DOMAIN
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.components.homeassistant import (
DOMAIN as HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
)
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
import homeassistant.helpers.issue_registry as ir
@ -252,3 +256,56 @@ async def test_updating_to_often(
)
await asyncio.sleep(0.2)
async def test_updating_manually(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test handling manual updating using homeassistant udate_entity service."""
await setup.async_setup_component(hass, HA_DOMAIN, {})
called = []
class MockCommandBinarySensor(CommandBinarySensor):
"""Mock entity that updates slow."""
async def _async_update(self) -> None:
"""Update slow."""
called.append(1)
# Add waiting time
await asyncio.sleep(1)
with patch(
"homeassistant.components.command_line.binary_sensor.CommandBinarySensor",
side_effect=MockCommandBinarySensor,
):
await setup.async_setup_component(
hass,
DOMAIN,
{
"command_line": [
{
"binary_sensor": {
"name": "Test",
"command": "echo 1",
"payload_on": "1",
"payload_off": "0",
"scan_interval": 10,
}
}
]
},
)
await hass.async_block_till_done()
assert len(called) == 1
await hass.services.async_call(
HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
{ATTR_ENTITY_ID: ["binary_sensor.test"]},
blocking=True,
)
await hass.async_block_till_done()
assert len(called) == 2
await asyncio.sleep(0.2)

View File

@ -13,6 +13,10 @@ from homeassistant import config as hass_config, setup
from homeassistant.components.command_line import DOMAIN
from homeassistant.components.command_line.cover import CommandCover
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN, SCAN_INTERVAL
from homeassistant.components.homeassistant import (
DOMAIN as HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_CLOSE_COVER,
@ -378,3 +382,57 @@ async def test_updating_to_often(
)
await asyncio.sleep(0.2)
async def test_updating_manually(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test handling manual updating using homeassistant udate_entity service."""
await setup.async_setup_component(hass, HA_DOMAIN, {})
called = []
class MockCommandCover(CommandCover):
"""Mock entity that updates slow."""
async def _async_update(self) -> None:
"""Update slow."""
called.append(1)
# Add waiting time
await asyncio.sleep(1)
with patch(
"homeassistant.components.command_line.cover.CommandCover",
side_effect=MockCommandCover,
):
await setup.async_setup_component(
hass,
DOMAIN,
{
"command_line": [
{
"cover": {
"command_state": "echo 1",
"value_template": "{{ value }}",
"name": "Test",
"scan_interval": 10,
}
}
]
},
)
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.now() + timedelta(seconds=10))
await hass.async_block_till_done()
assert len(called) == 1
await hass.services.async_call(
HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
{ATTR_ENTITY_ID: ["cover.test"]},
blocking=True,
)
await hass.async_block_till_done()
assert len(called) == 2
await asyncio.sleep(0.2)

View File

@ -11,7 +11,12 @@ import pytest
from homeassistant import setup
from homeassistant.components.command_line import DOMAIN
from homeassistant.components.command_line.sensor import CommandSensor
from homeassistant.components.homeassistant import (
DOMAIN as HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
)
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
import homeassistant.helpers.issue_registry as ir
@ -586,3 +591,54 @@ async def test_updating_to_often(
)
await asyncio.sleep(0.2)
async def test_updating_manually(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test handling manual updating using homeassistant udate_entity service."""
await setup.async_setup_component(hass, HA_DOMAIN, {})
called = []
class MockCommandSensor(CommandSensor):
"""Mock entity that updates slow."""
async def _async_update(self) -> None:
"""Update slow."""
called.append(1)
# Add waiting time
await asyncio.sleep(1)
with patch(
"homeassistant.components.command_line.sensor.CommandSensor",
side_effect=MockCommandSensor,
):
await setup.async_setup_component(
hass,
DOMAIN,
{
"command_line": [
{
"sensor": {
"name": "Test",
"command": "echo 1",
"scan_interval": 10,
}
}
]
},
)
await hass.async_block_till_done()
assert len(called) == 1
await hass.services.async_call(
HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
{ATTR_ENTITY_ID: ["sensor.test"]},
blocking=True,
)
await hass.async_block_till_done()
assert len(called) == 2
await asyncio.sleep(0.2)

View File

@ -14,6 +14,10 @@ import pytest
from homeassistant import setup
from homeassistant.components.command_line import DOMAIN
from homeassistant.components.command_line.switch import CommandSwitch
from homeassistant.components.homeassistant import (
DOMAIN as HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
)
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN, SCAN_INTERVAL
from homeassistant.const import (
ATTR_ENTITY_ID,
@ -696,3 +700,58 @@ async def test_updating_to_often(
)
await asyncio.sleep(0.2)
async def test_updating_manually(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test handling manual updating using homeassistant udate_entity service."""
await setup.async_setup_component(hass, HA_DOMAIN, {})
called = []
class MockCommandSwitch(CommandSwitch):
"""Mock entity that updates slow."""
async def _async_update(self) -> None:
"""Update slow."""
called.append(1)
# Add waiting time
await asyncio.sleep(1)
with patch(
"homeassistant.components.command_line.switch.CommandSwitch",
side_effect=MockCommandSwitch,
):
await setup.async_setup_component(
hass,
DOMAIN,
{
"command_line": [
{
"switch": {
"command_state": "echo 1",
"command_on": "echo 2",
"command_off": "echo 3",
"name": "Test",
"scan_interval": 10,
}
}
]
},
)
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.now() + timedelta(seconds=10))
await hass.async_block_till_done()
assert len(called) == 1
await hass.services.async_call(
HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
{ATTR_ENTITY_ID: ["switch.test"]},
blocking=True,
)
await hass.async_block_till_done()
assert len(called) == 2
await asyncio.sleep(0.2)