Add binary_sensor to Version integration (#66539)

* Add binary_sensor to version integration

* Add test to check we not create for local

* Move _attr_icon to sensor

* Update homeassistant/components/version/binary_sensor.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Joakim Sørensen 2022-02-15 16:39:34 +01:00 committed by GitHub
parent af4e37339a
commit 0d2712e436
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 130 additions and 29 deletions

View File

@ -0,0 +1,61 @@
"""Binary sensor platform for Version."""
from __future__ import annotations
from awesomeversion import AwesomeVersion
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME, __version__ as HA_VERSION
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import CONF_SOURCE, DEFAULT_NAME, DOMAIN
from .coordinator import VersionDataUpdateCoordinator
from .entity import VersionEntity
HA_VERSION_OBJECT = AwesomeVersion(HA_VERSION)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up version binary_sensors."""
coordinator: VersionDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
if (source := config_entry.data[CONF_SOURCE]) == "local":
return
if (entity_name := config_entry.data[CONF_NAME]) == DEFAULT_NAME:
entity_name = config_entry.title
entities: list[VersionBinarySensor] = [
VersionBinarySensor(
coordinator=coordinator,
entity_description=BinarySensorEntityDescription(
key=str(source),
name=f"{entity_name} Update Available",
device_class=BinarySensorDeviceClass.UPDATE,
entity_category=EntityCategory.DIAGNOSTIC,
),
)
]
async_add_entities(entities)
class VersionBinarySensor(VersionEntity, BinarySensorEntity):
"""Binary sensor for version entities."""
entity_description: BinarySensorEntityDescription
@property
def is_on(self) -> bool:
"""Return true if the binary sensor is on."""
version = self.coordinator.version
return version is not None and (version > HA_VERSION_OBJECT)

View File

@ -11,7 +11,7 @@ from homeassistant.const import CONF_NAME, Platform
DOMAIN: Final = "version"
LOGGER: Final[Logger] = getLogger(__package__)
PLATFORMS: Final[list[Platform]] = [Platform.SENSOR]
PLATFORMS: Final[list[Platform]] = [Platform.BINARY_SENSOR, Platform.SENSOR]
UPDATE_COORDINATOR_UPDATE_INTERVAL: Final[timedelta] = timedelta(minutes=5)
ENTRY_TYPE_SERVICE: Final = "service"

View File

@ -0,0 +1,33 @@
"""Common entity class for Version integration."""
from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo, EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, HOME_ASSISTANT
from .coordinator import VersionDataUpdateCoordinator
class VersionEntity(CoordinatorEntity):
"""Common entity class for Version integration."""
_attr_device_info = DeviceInfo(
name=f"{HOME_ASSISTANT} {DOMAIN.title()}",
identifiers={(HOME_ASSISTANT, DOMAIN)},
manufacturer=HOME_ASSISTANT,
entry_type=DeviceEntryType.SERVICE,
)
coordinator: VersionDataUpdateCoordinator
def __init__(
self,
coordinator: VersionDataUpdateCoordinator,
entity_description: EntityDescription,
) -> None:
"""Initialize version entities."""
super().__init__(coordinator)
self.entity_description = entity_description
self._attr_unique_id = (
f"{coordinator.config_entry.entry_id}_{entity_description.key}"
)

View File

@ -15,11 +15,8 @@ from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import (
ATTR_SOURCE,
@ -31,12 +28,12 @@ from .const import (
DEFAULT_NAME,
DEFAULT_SOURCE,
DOMAIN,
HOME_ASSISTANT,
LOGGER,
VALID_IMAGES,
VALID_SOURCES,
)
from .coordinator import VersionDataUpdateCoordinator
from .entity import VersionEntity
PLATFORM_SCHEMA: Final[Schema] = SENSOR_PLATFORM_SCHEMA.extend(
{
@ -91,30 +88,10 @@ async def async_setup_entry(
async_add_entities(version_sensor_entities)
class VersionSensorEntity(CoordinatorEntity, SensorEntity):
class VersionSensorEntity(VersionEntity, SensorEntity):
"""Version sensor entity class."""
_attr_icon = "mdi:package-up"
_attr_device_info = DeviceInfo(
name=f"{HOME_ASSISTANT} {DOMAIN.title()}",
identifiers={(HOME_ASSISTANT, DOMAIN)},
manufacturer=HOME_ASSISTANT,
entry_type=DeviceEntryType.SERVICE,
)
coordinator: VersionDataUpdateCoordinator
def __init__(
self,
coordinator: VersionDataUpdateCoordinator,
entity_description: SensorEntityDescription,
) -> None:
"""Initialize version sensor entities."""
super().__init__(coordinator)
self.entity_description = entity_description
self._attr_unique_id = (
f"{coordinator.config_entry.entry_id}_{entity_description.key}"
)
@property
def native_value(self) -> StateType:

View File

@ -52,9 +52,17 @@ async def mock_get_version_update(
await hass.async_block_till_done()
async def setup_version_integration(hass: HomeAssistant) -> MockConfigEntry:
async def setup_version_integration(
hass: HomeAssistant,
entry_data: dict[str, Any] | None = None,
) -> MockConfigEntry:
"""Set up the Version integration."""
mock_entry = MockConfigEntry(**MOCK_VERSION_CONFIG_ENTRY_DATA)
mock_entry = MockConfigEntry(
**{
**MOCK_VERSION_CONFIG_ENTRY_DATA,
"data": entry_data or MOCK_VERSION_CONFIG_ENTRY_DATA["data"],
}
)
mock_entry.add_to_hass(hass)
with patch(
@ -65,7 +73,6 @@ async def setup_version_integration(hass: HomeAssistant) -> MockConfigEntry:
assert await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
assert hass.states.get("sensor.local_installation").state == MOCK_VERSION
assert mock_entry.state == config_entries.ConfigEntryState.LOADED
return mock_entry

View File

@ -0,0 +1,23 @@
"""The test for the version binary sensor platform."""
from __future__ import annotations
from homeassistant.components.version.const import DEFAULT_CONFIGURATION
from homeassistant.core import HomeAssistant
from .common import setup_version_integration
async def test_version_binary_sensor_local_source(hass: HomeAssistant):
"""Test the Version binary sensor with local source."""
await setup_version_integration(hass)
state = hass.states.get("binary_sensor.local_installation_update_available")
assert not state
async def test_version_binary_sensor(hass: HomeAssistant):
"""Test the Version binary sensor."""
await setup_version_integration(hass, {**DEFAULT_CONFIGURATION, "source": "pypi"})
state = hass.states.get("binary_sensor.local_installation_update_available")
assert state