Skip to content

Commit

Permalink
Add scan interval
Browse files Browse the repository at this point in the history
  • Loading branch information
gjohansson-ST committed May 29, 2023
1 parent 8b662dc commit 7601c54
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 16 deletions.
25 changes: 23 additions & 2 deletions homeassistant/components/command_line/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,24 @@
from homeassistant.components.binary_sensor import (
DEVICE_CLASSES_SCHEMA as BINARY_SENSOR_DEVICE_CLASSES_SCHEMA,
DOMAIN as BINARY_SENSOR_DOMAIN,
SCAN_INTERVAL as BINARY_SENSOR_DEFAULT_SCAN_INTERVAL,
)
from homeassistant.components.cover import (
DOMAIN as COVER_DOMAIN,
SCAN_INTERVAL as COVER_DEFAULT_SCAN_INTERVAL,
)
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN
from homeassistant.components.notify import DOMAIN as NOTIFY_DOMAIN
from homeassistant.components.sensor import (
CONF_STATE_CLASS,
DEVICE_CLASSES_SCHEMA as SENSOR_DEVICE_CLASSES_SCHEMA,
DOMAIN as SENSOR_DOMAIN,
SCAN_INTERVAL as SENSOR_DEFAULT_SCAN_INTERVAL,
STATE_CLASSES_SCHEMA as SENSOR_STATE_CLASSES_SCHEMA,
)
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.components.switch import (
DOMAIN as SWITCH_DOMAIN,
SCAN_INTERVAL as SWITCH_DEFAULT_SCAN_INTERVAL,
)
from homeassistant.const import (
CONF_COMMAND,
CONF_COMMAND_CLOSE,
Expand All @@ -34,6 +42,7 @@
CONF_NAME,
CONF_PAYLOAD_OFF,
CONF_PAYLOAD_ON,
CONF_SCAN_INTERVAL,
CONF_UNIQUE_ID,
CONF_UNIT_OF_MEASUREMENT,
CONF_VALUE_TEMPLATE,
Expand Down Expand Up @@ -74,6 +83,9 @@
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,
vol.Optional(
CONF_SCAN_INTERVAL, default=BINARY_SENSOR_DEFAULT_SCAN_INTERVAL
): vol.All(cv.time_period, cv.positive_timedelta),
}
)
COVER_SCHEMA = vol.Schema(
Expand All @@ -86,6 +98,9 @@
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,
vol.Optional(CONF_SCAN_INTERVAL, default=COVER_DEFAULT_SCAN_INTERVAL): vol.All(
cv.time_period, cv.positive_timedelta
),
}
)
NOTIFY_SCHEMA = vol.Schema(
Expand All @@ -106,6 +121,9 @@
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_DEVICE_CLASS): SENSOR_DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_STATE_CLASS): SENSOR_STATE_CLASSES_SCHEMA,
vol.Optional(CONF_SCAN_INTERVAL, default=SENSOR_DEFAULT_SCAN_INTERVAL): vol.All(
cv.time_period, cv.positive_timedelta
),
}
)
SWITCH_SCHEMA = vol.Schema(
Expand All @@ -118,6 +136,9 @@
vol.Optional(CONF_ICON): cv.template,
vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=SWITCH_DEFAULT_SCAN_INTERVAL): vol.All(
cv.time_period, cv.positive_timedelta
),
}
)
COMBINED_SCHEMA = vol.Schema(
Expand Down
24 changes: 23 additions & 1 deletion homeassistant/components/command_line/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
CONF_NAME,
CONF_PAYLOAD_OFF,
CONF_PAYLOAD_ON,
CONF_SCAN_INTERVAL,
CONF_UNIQUE_ID,
CONF_VALUE_TEMPLATE,
)
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.template import Template
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
Expand Down Expand Up @@ -84,6 +86,9 @@ async def async_setup_platform(
value_template: Template | None = binary_sensor_config.get(CONF_VALUE_TEMPLATE)
command_timeout: int = binary_sensor_config[CONF_COMMAND_TIMEOUT]
unique_id: str | None = binary_sensor_config.get(CONF_UNIQUE_ID)
scan_interval: timedelta = binary_sensor_config.get(
CONF_SCAN_INTERVAL, SCAN_INTERVAL
)
if value_template is not None:
value_template.hass = hass
data = CommandSensorData(hass, command, command_timeout)
Expand All @@ -98,6 +103,7 @@ async def async_setup_platform(
payload_off,
value_template,
unique_id,
scan_interval,
)
],
True,
Expand All @@ -107,6 +113,8 @@ async def async_setup_platform(
class CommandBinarySensor(BinarySensorEntity):
"""Representation of a command line binary sensor."""

_attr_should_poll = False

def __init__(
self,
data: CommandSensorData,
Expand All @@ -116,6 +124,7 @@ def __init__(
payload_off: str,
value_template: Template | None,
unique_id: str | None,
scan_interval: timedelta,
) -> None:
"""Initialize the Command line binary sensor."""
self.data = data
Expand All @@ -126,8 +135,19 @@ def __init__(
self._payload_off = payload_off
self._value_template = value_template
self._attr_unique_id = unique_id
self._scan_interval = scan_interval

async def async_added_to_hass(self) -> None:
"""Call when entity about to be added to hass."""
await super().async_added_to_hass()
await self._async_update(None)
self.async_on_remove(
async_track_time_interval(
self.hass, self._async_update, self._scan_interval
),
)

async def async_update(self) -> None:
async def _async_update(self, now) -> None:
"""Get the latest data and updates the state."""
await self.hass.async_add_executor_job(self.data.update)
value = self.data.value
Expand All @@ -141,3 +161,5 @@ async def async_update(self) -> None:
self._attr_is_on = True
elif value == self._payload_off:
self._attr_is_on = False

self.async_write_ha_state()
39 changes: 31 additions & 8 deletions homeassistant/components/command_line/cover.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Support for command line covers."""
from __future__ import annotations

from datetime import timedelta
import logging
from typing import TYPE_CHECKING, Any

Expand All @@ -19,12 +20,14 @@
CONF_COVERS,
CONF_FRIENDLY_NAME,
CONF_NAME,
CONF_SCAN_INTERVAL,
CONF_UNIQUE_ID,
CONF_VALUE_TEMPLATE,
)
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.template import Template
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
Expand All @@ -33,6 +36,8 @@
from .const import CONF_COMMAND_TIMEOUT, DEFAULT_TIMEOUT, DOMAIN
from .utils import call_shell_with_timeout, check_output_or_log

SCAN_INTERVAL = timedelta(seconds=15)

_LOGGER = logging.getLogger(__name__)

COVER_SCHEMA = vol.Schema(
Expand Down Expand Up @@ -97,6 +102,7 @@ async def async_setup_platform(
value_template,
device_config[CONF_COMMAND_TIMEOUT],
device_config.get(CONF_UNIQUE_ID),
device_config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL),
)
)

Expand All @@ -110,6 +116,8 @@ async def async_setup_platform(
class CommandCover(CoverEntity):
"""Representation a command line cover."""

_attr_should_poll = False

def __init__(
self,
name: str,
Expand All @@ -120,6 +128,7 @@ def __init__(
value_template: Template | None,
timeout: int,
unique_id: str | None,
scan_interval: timedelta,
) -> None:
"""Initialize the cover."""
self._attr_name = name
Expand All @@ -131,7 +140,17 @@ def __init__(
self._value_template = value_template
self._timeout = timeout
self._attr_unique_id = unique_id
self._attr_should_poll = bool(command_state)
self._scan_interval = scan_interval

async def async_added_to_hass(self) -> None:
"""Call when entity about to be added to hass."""
await super().async_added_to_hass()
if self._command_state:
self.async_on_remove(
async_track_time_interval(
self.hass, self._async_update, self._scan_interval
),
)

def _move_cover(self, command: str) -> bool:
"""Execute the actual commands."""
Expand Down Expand Up @@ -170,7 +189,7 @@ def _query_state(self) -> str | None:
if TYPE_CHECKING:
return None

async def async_update(self) -> None:
async def _async_update(self, now) -> None:
"""Update device state."""
if self._command_state:
payload = str(await self.hass.async_add_executor_job(self._query_state))
Expand All @@ -181,15 +200,19 @@ async def async_update(self) -> None:
self._state = None
if payload:
self._state = int(payload)
await self.async_update_ha_state(True)

def open_cover(self, **kwargs: Any) -> None:
async def async_open_cover(self, **kwargs: Any) -> None:
"""Open the cover."""
self._move_cover(self._command_open)
await self.hass.async_add_executor_job(self._move_cover, self._command_open)
await self._async_update(None)

def close_cover(self, **kwargs: Any) -> None:
async def async_close_cover(self, **kwargs: Any) -> None:
"""Close the cover."""
self._move_cover(self._command_close)
await self.hass.async_add_executor_job(self._move_cover, self._command_close)
await self._async_update(None)

def stop_cover(self, **kwargs: Any) -> None:
async def async_stop_cover(self, **kwargs: Any) -> None:
"""Stop the cover."""
self._move_cover(self._command_stop)
await self.hass.async_add_executor_job(self._move_cover, self._command_stop)
await self._async_update(None)
25 changes: 22 additions & 3 deletions homeassistant/components/command_line/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
CONF_COMMAND,
CONF_DEVICE_CLASS,
CONF_NAME,
CONF_SCAN_INTERVAL,
CONF_UNIQUE_ID,
CONF_UNIT_OF_MEASUREMENT,
CONF_VALUE_TEMPLATE,
Expand All @@ -28,6 +29,7 @@
from homeassistant.exceptions import TemplateError
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.template import Template
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
Expand Down Expand Up @@ -88,6 +90,7 @@ async def async_setup_platform(
if value_template is not None:
value_template.hass = hass
json_attributes: list[str] | None = sensor_config.get(CONF_JSON_ATTRIBUTES)
scan_interval: timedelta = sensor_config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL)
data = CommandSensorData(hass, command, command_timeout)

async_add_entities(
Expand All @@ -99,15 +102,17 @@ async def async_setup_platform(
value_template,
json_attributes,
unique_id,
scan_interval,
)
],
True,
]
)


class CommandSensor(SensorEntity):
"""Representation of a sensor that is using shell commands."""

_attr_should_poll = False

def __init__(
self,
data: CommandSensorData,
Expand All @@ -116,6 +121,7 @@ def __init__(
value_template: Template | None,
json_attributes: list[str] | None,
unique_id: str | None,
scan_interval: timedelta,
) -> None:
"""Initialize the sensor."""
self._attr_name = name
Expand All @@ -126,8 +132,19 @@ def __init__(
self._value_template = value_template
self._attr_native_unit_of_measurement = unit_of_measurement
self._attr_unique_id = unique_id
self._scan_interval = scan_interval

async def async_added_to_hass(self) -> None:
"""Call when entity about to be added to hass."""
await super().async_added_to_hass()
await self._async_update(None)
self.async_on_remove(
async_track_time_interval(
self.hass, self._async_update, self._scan_interval
),
)

async def async_update(self) -> None:
async def _async_update(self, now) -> None:
"""Get the latest data and updates the state."""
await self.hass.async_add_executor_job(self.data.update)
value = self.data.value
Expand Down Expand Up @@ -163,6 +180,8 @@ async def async_update(self) -> None:
else:
self._attr_native_value = value

self.async_write_ha_state()


class CommandSensorData:
"""The class for handling the data retrieval."""
Expand Down
Loading

0 comments on commit 7601c54

Please sign in to comment.