Add more shopping list services (#45591)
Co-authored-by: Franck Nijhof <git@frenck.dev>pull/46976/head
parent
d96249e39c
commit
23b2953773
|
@ -15,17 +15,21 @@ from homeassistant.util.json import load_json, save_json
|
|||
from .const import DOMAIN
|
||||
|
||||
ATTR_NAME = "name"
|
||||
ATTR_COMPLETE = "complete"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
CONFIG_SCHEMA = vol.Schema({DOMAIN: {}}, extra=vol.ALLOW_EXTRA)
|
||||
EVENT = "shopping_list_updated"
|
||||
ITEM_UPDATE_SCHEMA = vol.Schema({"complete": bool, ATTR_NAME: str})
|
||||
ITEM_UPDATE_SCHEMA = vol.Schema({ATTR_COMPLETE: bool, ATTR_NAME: str})
|
||||
PERSISTENCE = ".shopping_list.json"
|
||||
|
||||
SERVICE_ADD_ITEM = "add_item"
|
||||
SERVICE_COMPLETE_ITEM = "complete_item"
|
||||
|
||||
SERVICE_INCOMPLETE_ITEM = "incomplete_item"
|
||||
SERVICE_COMPLETE_ALL = "complete_all"
|
||||
SERVICE_INCOMPLETE_ALL = "incomplete_all"
|
||||
SERVICE_ITEM_SCHEMA = vol.Schema({vol.Required(ATTR_NAME): vol.Any(None, cv.string)})
|
||||
SERVICE_LIST_SCHEMA = vol.Schema({})
|
||||
|
||||
WS_TYPE_SHOPPING_LIST_ITEMS = "shopping_list/items"
|
||||
WS_TYPE_SHOPPING_LIST_ADD_ITEM = "shopping_list/items/add"
|
||||
|
@ -92,6 +96,27 @@ async def async_setup_entry(hass, config_entry):
|
|||
else:
|
||||
await data.async_update(item["id"], {"name": name, "complete": True})
|
||||
|
||||
async def incomplete_item_service(call):
|
||||
"""Mark the item provided via `name` as incomplete."""
|
||||
data = hass.data[DOMAIN]
|
||||
name = call.data.get(ATTR_NAME)
|
||||
if name is None:
|
||||
return
|
||||
try:
|
||||
item = [item for item in data.items if item["name"] == name][0]
|
||||
except IndexError:
|
||||
_LOGGER.error("Restoring of item failed: %s cannot be found", name)
|
||||
else:
|
||||
await data.async_update(item["id"], {"name": name, "complete": False})
|
||||
|
||||
async def complete_all_service(call):
|
||||
"""Mark all items in the list as complete."""
|
||||
await data.async_update_list({"complete": True})
|
||||
|
||||
async def incomplete_all_service(call):
|
||||
"""Mark all items in the list as incomplete."""
|
||||
await data.async_update_list({"complete": False})
|
||||
|
||||
data = hass.data[DOMAIN] = ShoppingData(hass)
|
||||
await data.async_load()
|
||||
|
||||
|
@ -101,6 +126,24 @@ async def async_setup_entry(hass, config_entry):
|
|||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_COMPLETE_ITEM, complete_item_service, schema=SERVICE_ITEM_SCHEMA
|
||||
)
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_INCOMPLETE_ITEM,
|
||||
incomplete_item_service,
|
||||
schema=SERVICE_ITEM_SCHEMA,
|
||||
)
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_COMPLETE_ALL,
|
||||
complete_all_service,
|
||||
schema=SERVICE_LIST_SCHEMA,
|
||||
)
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_INCOMPLETE_ALL,
|
||||
incomplete_all_service,
|
||||
schema=SERVICE_LIST_SCHEMA,
|
||||
)
|
||||
|
||||
hass.http.register_view(ShoppingListView)
|
||||
hass.http.register_view(CreateShoppingListItemView)
|
||||
|
@ -165,6 +208,13 @@ class ShoppingData:
|
|||
self.items = [itm for itm in self.items if not itm["complete"]]
|
||||
await self.hass.async_add_executor_job(self.save)
|
||||
|
||||
async def async_update_list(self, info):
|
||||
"""Update all items in the list."""
|
||||
for item in self.items:
|
||||
item.update(info)
|
||||
await self.hass.async_add_executor_job(self.save)
|
||||
return self.items
|
||||
|
||||
@callback
|
||||
def async_reorder(self, item_ids):
|
||||
"""Reorder items."""
|
||||
|
|
|
@ -21,3 +21,16 @@ complete_item:
|
|||
example: Beer
|
||||
selector:
|
||||
text:
|
||||
|
||||
incomplete_item:
|
||||
description: Marks an item as incomplete in the shopping list.
|
||||
fields:
|
||||
name:
|
||||
description: The name of the item to mark as incomplete.
|
||||
example: Beer
|
||||
|
||||
complete_all:
|
||||
description: Marks all items as completed in the shopping list. It does not remove the items.
|
||||
|
||||
incomplete_all:
|
||||
description: Marks all items as incomplete in the shopping list.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Test shopping list component."""
|
||||
|
||||
from homeassistant.components.shopping_list.const import DOMAIN
|
||||
from homeassistant.components.websocket_api.const import (
|
||||
ERR_INVALID_FORMAT,
|
||||
ERR_NOT_FOUND,
|
||||
|
@ -19,6 +20,39 @@ async def test_add_item(hass, sl_setup):
|
|||
assert response.speech["plain"]["speech"] == "I've added beer to your shopping list"
|
||||
|
||||
|
||||
async def test_update_list(hass, sl_setup):
|
||||
"""Test updating all list items."""
|
||||
await intent.async_handle(
|
||||
hass, "test", "HassShoppingListAddItem", {"item": {"value": "beer"}}
|
||||
)
|
||||
|
||||
await intent.async_handle(
|
||||
hass, "test", "HassShoppingListAddItem", {"item": {"value": "cheese"}}
|
||||
)
|
||||
|
||||
# Update a single attribute, other attributes shouldn't change
|
||||
await hass.data[DOMAIN].async_update_list({"complete": True})
|
||||
|
||||
beer = hass.data[DOMAIN].items[0]
|
||||
assert beer["name"] == "beer"
|
||||
assert beer["complete"] is True
|
||||
|
||||
cheese = hass.data[DOMAIN].items[1]
|
||||
assert cheese["name"] == "cheese"
|
||||
assert cheese["complete"] is True
|
||||
|
||||
# Update multiple attributes
|
||||
await hass.data[DOMAIN].async_update_list({"name": "dupe", "complete": False})
|
||||
|
||||
beer = hass.data[DOMAIN].items[0]
|
||||
assert beer["name"] == "dupe"
|
||||
assert beer["complete"] is False
|
||||
|
||||
cheese = hass.data[DOMAIN].items[1]
|
||||
assert cheese["name"] == "dupe"
|
||||
assert cheese["complete"] is False
|
||||
|
||||
|
||||
async def test_recent_items_intent(hass, sl_setup):
|
||||
"""Test recent items."""
|
||||
|
||||
|
|
Loading…
Reference in New Issue