mirror of
https://github.com/home-assistant/core.git
synced 2026-09-28 02:18:10 -04:00
205 lines
6.7 KiB
Python
205 lines
6.7 KiB
Python
"""Platform for Alexa To-do integration."""
|
|
|
|
from typing import TYPE_CHECKING, override
|
|
|
|
from aioamazondevices.structures import (
|
|
AmazonListInfo,
|
|
AmazonListItemStatus,
|
|
AmazonListType,
|
|
)
|
|
|
|
from homeassistant.components.todo import (
|
|
TodoItem,
|
|
TodoItemStatus,
|
|
TodoListEntity,
|
|
TodoListEntityFeature,
|
|
)
|
|
from homeassistant.helpers.entity import EntityDescription
|
|
|
|
from .const import _LOGGER
|
|
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator, alexa_api_call
|
|
from .entity import AmazonServiceEntity
|
|
|
|
if TYPE_CHECKING:
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
|
|
|
|
PARALLEL_UPDATES = 0
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
entry: AmazonConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the Alexa To-do Lists platform."""
|
|
coordinator = entry.runtime_data
|
|
|
|
known_list_ids: set[str] = set()
|
|
|
|
def _check_lists() -> None:
|
|
current_list_ids = {todo_list.id for todo_list in coordinator.api.todo_lists}
|
|
new_list_ids = current_list_ids - known_list_ids
|
|
if new_list_ids:
|
|
known_list_ids.update(new_list_ids)
|
|
async_add_entities(
|
|
[
|
|
AlexaToDoList(coordinator, alexa_list)
|
|
for alexa_list in coordinator.api.todo_lists
|
|
if alexa_list.id in new_list_ids
|
|
]
|
|
)
|
|
|
|
_check_lists()
|
|
entry.async_on_unload(coordinator.async_add_listener(_check_lists))
|
|
|
|
|
|
class AlexaToDoList(AmazonServiceEntity, TodoListEntity):
|
|
"""Representation of an Alexa to-do list."""
|
|
|
|
_attr_supported_features = (
|
|
TodoListEntityFeature.CREATE_TODO_ITEM
|
|
| TodoListEntityFeature.UPDATE_TODO_ITEM
|
|
| TodoListEntityFeature.DELETE_TODO_ITEM
|
|
)
|
|
|
|
def __init__(
|
|
self, coordinator: AmazonDevicesCoordinator, alexa_list: AmazonListInfo
|
|
) -> None:
|
|
"""Initialize an Alexa to-do list entity."""
|
|
self._list = alexa_list
|
|
|
|
if alexa_list.list_type == AmazonListType.CUSTOM:
|
|
# Custom list -> Use actual name
|
|
entity_description = EntityDescription(
|
|
key=alexa_list.id, name=alexa_list.name
|
|
)
|
|
else:
|
|
entity_description = EntityDescription(
|
|
key=alexa_list.id,
|
|
translation_key=alexa_list.list_type.value.lower(),
|
|
)
|
|
|
|
super().__init__(coordinator, entity_description)
|
|
|
|
_LOGGER.debug(
|
|
"Created todo entity for list: %s (ID: %s)", self._list.name, self._list.id
|
|
)
|
|
|
|
@property
|
|
@override
|
|
def todo_items(self) -> list[TodoItem]:
|
|
"""Return all to-do items in the list."""
|
|
|
|
todo_items = self.coordinator.todo_list_items.get(self._list.id, {}).values()
|
|
|
|
return [
|
|
TodoItem(
|
|
uid=item.id,
|
|
summary=item.name,
|
|
status=TodoItemStatus.COMPLETED
|
|
if item.status == AmazonListItemStatus.COMPLETE
|
|
else TodoItemStatus.NEEDS_ACTION,
|
|
)
|
|
for item in todo_items
|
|
]
|
|
|
|
@override
|
|
async def async_create_todo_item(self, item: TodoItem) -> None:
|
|
"""Add an item to the To-do list."""
|
|
_LOGGER.debug(
|
|
"Creating todo item: %s for list: %s", item.summary, self._list.name
|
|
)
|
|
|
|
# For passing type checking, existence of summary
|
|
# is already checked by voluptuous
|
|
if TYPE_CHECKING:
|
|
assert item.summary is not None
|
|
|
|
async with alexa_api_call(self.coordinator):
|
|
await self.coordinator.api.add_todo_list_item(self._list.id, item.summary)
|
|
|
|
_LOGGER.debug(
|
|
"Successfully created todo item: %s for list: %s",
|
|
item.summary,
|
|
self._list.name,
|
|
)
|
|
|
|
@override
|
|
async def async_delete_todo_items(self, uids: list[str]) -> None:
|
|
"""Delete items from the to-do list."""
|
|
_LOGGER.debug("Called async_delete_todo_items for %s item(s)", len(uids))
|
|
|
|
list_items_lookup = self.coordinator.todo_list_items[self._list.id]
|
|
|
|
for uid in uids:
|
|
existing_item = list_items_lookup[uid]
|
|
|
|
_LOGGER.debug(
|
|
"Deleting item %s (ID: %s) with version %s",
|
|
existing_item.name,
|
|
uid,
|
|
existing_item.version,
|
|
)
|
|
async with alexa_api_call(self.coordinator):
|
|
await self.coordinator.api.delete_todo_list_item(
|
|
self._list.id, uid, existing_item.version
|
|
)
|
|
_LOGGER.debug(
|
|
"Successfully deleted item %s (ID: %s) with version %s",
|
|
existing_item.name,
|
|
uid,
|
|
existing_item.version,
|
|
)
|
|
|
|
@override
|
|
async def async_update_todo_item(self, item: TodoItem) -> None:
|
|
"""Update an item in the To-do list."""
|
|
list_items_lookup = self.coordinator.todo_list_items[self._list.id]
|
|
|
|
# For passing type checking, existence of UID and summary
|
|
# is already checked by voluptuous
|
|
if TYPE_CHECKING:
|
|
assert item.uid is not None
|
|
assert item.summary is not None
|
|
|
|
existing_item = list_items_lookup[item.uid]
|
|
|
|
if has_completed_changed := (
|
|
existing_item.status == AmazonListItemStatus.COMPLETE
|
|
) != (item.status == TodoItemStatus.COMPLETED):
|
|
# Update the checked status
|
|
_LOGGER.debug(
|
|
"Updating item %s with checked status %s", item.uid, item.status
|
|
)
|
|
|
|
async with alexa_api_call(self.coordinator):
|
|
await self.coordinator.api.set_todo_list_item_checked_status(
|
|
self._list.id,
|
|
item.uid,
|
|
item.status == TodoItemStatus.COMPLETED,
|
|
existing_item.version,
|
|
)
|
|
|
|
_LOGGER.debug(
|
|
"Successfully updated item %s with checked status %s",
|
|
item.uid,
|
|
item.status,
|
|
)
|
|
|
|
if existing_item.name != item.summary:
|
|
# Name has changed, update it
|
|
_LOGGER.debug("Updating item %s with new name %s", item.uid, item.summary)
|
|
|
|
# If both have changed -> Increase item version by 1
|
|
version = existing_item.version + int(has_completed_changed)
|
|
|
|
async with alexa_api_call(self.coordinator):
|
|
await self.coordinator.api.rename_todo_list_item(
|
|
self._list.id, item.uid, item.summary, version
|
|
)
|
|
_LOGGER.debug(
|
|
"Successfully updated item %s with new name %s", item.uid, item.summary
|
|
)
|