diff --git a/homeassistant/components/bring/const.py b/homeassistant/components/bring/const.py index 64a6ec67f85..911c08a835d 100644 --- a/homeassistant/components/bring/const.py +++ b/homeassistant/components/bring/const.py @@ -1,3 +1,11 @@ """Constants for the Bring! integration.""" +from typing import Final + DOMAIN = "bring" + +ATTR_SENDER: Final = "sender" +ATTR_ITEM_NAME: Final = "item" +ATTR_NOTIFICATION_TYPE: Final = "message" + +SERVICE_PUSH_NOTIFICATION = "send_message" diff --git a/homeassistant/components/bring/icons.json b/homeassistant/components/bring/icons.json index a757b20a4cc..1c6c3bdeca0 100644 --- a/homeassistant/components/bring/icons.json +++ b/homeassistant/components/bring/icons.json @@ -5,5 +5,8 @@ "default": "mdi:cart" } } + }, + "services": { + "send_message": "mdi:cellphone-message" } } diff --git a/homeassistant/components/bring/services.yaml b/homeassistant/components/bring/services.yaml new file mode 100644 index 00000000000..98d5c68de13 --- /dev/null +++ b/homeassistant/components/bring/services.yaml @@ -0,0 +1,23 @@ +send_message: + target: + entity: + domain: todo + integration: bring + fields: + message: + example: urgent_message + required: true + default: "going_shopping" + selector: + select: + translation_key: "notification_type_selector" + options: + - "going_shopping" + - "changed_list" + - "shopping_done" + - "urgent_message" + item: + example: Cilantro + required: false + selector: + text: diff --git a/homeassistant/components/bring/strings.json b/homeassistant/components/bring/strings.json index 6d61034bea8..e6df885cbbc 100644 --- a/homeassistant/components/bring/strings.json +++ b/homeassistant/components/bring/strings.json @@ -38,6 +38,42 @@ }, "setup_authentication_exception": { "message": "Authentication failed for {email}, check your email and password" + }, + "notify_missing_argument_item": { + "message": "Failed to call service {service}. 'URGENT_MESSAGE' requires a value @ data['item']. Got None" + }, + "notify_request_failed": { + "message": "Failed to send push notification for bring due to a connection error, try again later" + } + }, + "services": { + "send_message": { + "name": "[%key:component::notify::services::notify::name%]", + "description": "Send a mobile push notification to members of a shared Bring! list.", + "fields": { + "entity_id": { + "name": "List", + "description": "Bring! list whose members (except sender) will be notified." + }, + "message": { + "name": "Notification type", + "description": "Type of push notification to send to list members." + }, + "item": { + "name": "Item (Required if message type `Breaking news` selected)", + "description": "Item name to include in a breaking news message e.g. `Breaking news - Please get cilantro!`" + } + } + } + }, + "selector": { + "notification_type_selector": { + "options": { + "going_shopping": "I'm going shopping! - Last chance for adjustments", + "changed_list": "List changed - Check it out", + "shopping_done": "Shopping done - you can relax", + "urgent_message": "Breaking news - Please get `item`!" + } } } } diff --git a/homeassistant/components/bring/todo.py b/homeassistant/components/bring/todo.py index e631dc32951..5eabcc01553 100644 --- a/homeassistant/components/bring/todo.py +++ b/homeassistant/components/bring/todo.py @@ -6,7 +6,8 @@ from typing import TYPE_CHECKING import uuid from bring_api.exceptions import BringRequestException -from bring_api.types import BringItem, BringItemOperation +from bring_api.types import BringItem, BringItemOperation, BringNotificationType +import voluptuous as vol from homeassistant.components.todo import ( TodoItem, @@ -16,11 +17,18 @@ from homeassistant.components.todo import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.exceptions import HomeAssistantError +from homeassistant.exceptions import HomeAssistantError, ServiceValidationError +from homeassistant.helpers import config_validation as cv, entity_platform +from homeassistant.helpers.config_validation import make_entity_service_schema from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DOMAIN +from .const import ( + ATTR_ITEM_NAME, + ATTR_NOTIFICATION_TYPE, + DOMAIN, + SERVICE_PUSH_NOTIFICATION, +) from .coordinator import BringData, BringDataUpdateCoordinator @@ -46,6 +54,21 @@ async def async_setup_entry( for bring_list in coordinator.data.values() ) + platform = entity_platform.async_get_current_platform() + + platform.async_register_entity_service( + SERVICE_PUSH_NOTIFICATION, + make_entity_service_schema( + { + vol.Required(ATTR_NOTIFICATION_TYPE): vol.All( + vol.Upper, cv.enum(BringNotificationType) + ), + vol.Optional(ATTR_ITEM_NAME): cv.string, + } + ), + "async_send_message", + ) + class BringTodoListEntity( CoordinatorEntity[BringDataUpdateCoordinator], TodoListEntity @@ -231,3 +254,26 @@ class BringTodoListEntity( ) from e await self.coordinator.async_refresh() + + async def async_send_message( + self, + message: BringNotificationType, + item: str | None = None, + ) -> None: + """Send a push notification to members of a shared bring list.""" + + try: + await self.coordinator.bring.notify(self._list_uuid, message, item or None) + except BringRequestException as e: + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="notify_request_failed", + ) from e + except ValueError as e: + raise ServiceValidationError( + translation_domain=DOMAIN, + translation_key="notify_missing_argument_item", + translation_placeholders={ + "service": f"{DOMAIN}.{SERVICE_PUSH_NOTIFICATION}", + }, + ) from e