Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add update entity and state class to batteries #114

Merged
merged 3 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions custom_components/vivint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
Platform.LOCK,
Platform.SENSOR,
Platform.SWITCH,
Platform.UPDATE,
]

ATTR_TYPE = "type"
Expand Down
5 changes: 2 additions & 3 deletions custom_components/vivint/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,8 @@ def __init__(
self.hub = hub
self.entity_description = entity_description

self._attr_unique_id = (
f"{device.alarm_panel.id}-{device.id}-{entity_description.key}"
)
prefix = f"{device.alarm_panel.id}-" if device.alarm_panel else ""
self._attr_unique_id = f"{prefix}{device.id}-{entity_description.key}"
device = self.device.parent if self.device.is_subdevice else self.device
self._attr_device_info = DeviceInfo(
identifiers={get_device_id(device)},
Expand Down
4 changes: 2 additions & 2 deletions custom_components/vivint/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"iot_class": "cloud_push",
"issue_tracker": "https://github.com/natekspencer/hacs-vivint/issues",
"loggers": ["custom_components.vivint", "vivintpy"],
"requirements": ["vivintpy==2023.3.5"],
"version": "2023.8.0",
"requirements": ["vivintpy==2023.3.6"],
"version": "2023.8.1",
"zeroconf": ["_vivint-ODC300._tcp.local.", "_vivint-DBC350._tcp.local."]
}
2 changes: 2 additions & 0 deletions custom_components/vivint/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
DOMAIN as SENSOR_DOMAIN,
SensorDeviceClass,
SensorEntity,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE
Expand Down Expand Up @@ -68,6 +69,7 @@ class VivintBatterySensorEntity(VivintEntity, SensorEntity):
_attr_device_class = SensorDeviceClass.BATTERY
_attr_entity_category = EntityCategory.DIAGNOSTIC
_attr_native_unit_of_measurement = PERCENTAGE
_attr_state_class = SensorStateClass.MEASUREMENT

@property
def name(self) -> str:
Expand Down
96 changes: 96 additions & 0 deletions custom_components/vivint/update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
"""Support for Vivint updates."""
from __future__ import annotations

from datetime import timedelta
from typing import Any

from vivintpy.devices.alarm_panel import AlarmPanel
from vivintpy.entity import UPDATE

from homeassistant.components.update import (
UpdateDeviceClass,
UpdateEntity,
UpdateEntityDescription,
UpdateEntityFeature as Feature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN
from .hub import VivintBaseEntity, VivintHub

SCAN_INTERVAL = timedelta(days=1)

FIRMWARE_UPDATE_ENTITY = UpdateEntityDescription(
key="firmware", name="Firmware", device_class=UpdateDeviceClass.FIRMWARE
)


async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Litter-Robot update platform."""
hub: VivintHub = hass.data[DOMAIN][entry.entry_id]
entities = [
VivintUpdateEntity(
device=alarm_panel, hub=hub, entity_description=FIRMWARE_UPDATE_ENTITY
)
for system in hub.account.systems
if system.is_admin
for alarm_panel in system.alarm_panels
]
async_add_entities(entities, True)


class VivintUpdateEntity(VivintBaseEntity, UpdateEntity):
"""A class that describes device update entities."""

device: AlarmPanel

_attr_supported_features = Feature.INSTALL | Feature.PROGRESS

@property
def in_progress(self) -> bool:
"""Update installation progress."""
return self.device._AlarmPanel__panel.data["sus"] != "Idle"

@property
def installed_version(self) -> str:
"""Version installed and in use."""
return self.device.software_version

@property
def should_poll(self) -> bool:
"""Set polling to True."""
return True

async def async_update(self) -> None:
"""Update the entity."""
software_update = await self.device.get_software_update_details()
if software_update.get("available"):
latest_version = software_update["available_version"]
else:
latest_version = self.device.software_version
self._attr_latest_version = latest_version

async def async_install(
self, version: str | None, backup: bool, **kwargs: Any
) -> None:
"""Install an update."""
if (await self.device.get_software_update_details()).get("available"):
if not await self.device.update_software():
message = f"Unable to start firmware update on {self.device.name}"
raise HomeAssistantError(message)

async def async_added_to_hass(self) -> None:
"""Set up a listener for the entity."""
await super().async_added_to_hass()
self.async_on_remove(
self.device._AlarmPanel__panel.on(
UPDATE, lambda _: self.async_write_ha_state()
)
)