1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-17 15:44:52 +01:00

Add html5.dismiss_message action to HTML5 integration (#166909)

This commit is contained in:
Manu
2026-03-31 19:02:58 +02:00
committed by GitHub
parent 5425e82fb4
commit cda1974e40
7 changed files with 153 additions and 12 deletions

View File

@@ -10,8 +10,11 @@
"dismiss": {
"service": "mdi:bell-off"
},
"dismiss_message": {
"service": "mdi:comment-remove"
},
"send_message": {
"service": "mdi:message-arrow-right"
"service": "mdi:comment-arrow-right"
}
}
}

View File

@@ -29,3 +29,22 @@ def deprecated_notify_action_call(
translation_key="deprecated_notify_action",
translation_placeholders={"action": action},
)
@callback
def deprecated_dismiss_action_call(hass: HomeAssistant) -> None:
"""Deprecated action call."""
async_create_issue(
hass,
DOMAIN,
"deprecated_dismiss_action",
breaks_in_ha_version="2026.11.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_dismiss_action",
translation_placeholders={
"action": "html5.dismiss",
"new_action": "html5.dismiss_message",
},
)

View File

@@ -60,7 +60,7 @@ from .const import (
SERVICE_DISMISS,
)
from .entity import HTML5Entity, Registration
from .issue import deprecated_notify_action_call
from .issue import deprecated_dismiss_action_call, deprecated_notify_action_call
_LOGGER = logging.getLogger(__name__)
@@ -460,6 +460,9 @@ class HTML5NotificationService(BaseNotificationService):
This method must be run in the event loop.
"""
deprecated_dismiss_action_call(self.hass)
data: dict[str, Any] | None = kwargs.get(ATTR_DATA)
tag: str = data.get(ATTR_TAG, "") if data else ""
payload = {ATTR_TAG: tag, ATTR_DISMISS: True, ATTR_DATA: {}}
@@ -624,6 +627,11 @@ class HTML5NotifyEntity(HTML5Entity, NotifyEntity):
await self._webpush(**kwargs)
self._async_record_notification()
async def dismiss_notification(self, tag: str = "") -> None:
"""Dismiss a message via html5.dismiss_message action."""
await self._webpush(dismiss=True, tag=tag)
self._async_record_notification()
async def _webpush(
self,
message: str | None = None,

View File

@@ -32,6 +32,7 @@ from .const import (
)
SERVICE_SEND_MESSAGE = "send_message"
SERVICE_DISMISS_MESSAGE = "dismiss_message"
SERVICE_SEND_MESSAGE_SCHEMA = cv.make_entity_service_schema(
{
@@ -67,6 +68,10 @@ SERVICE_SEND_MESSAGE_SCHEMA = cv.make_entity_service_schema(
}
)
SERVICE_DISMISS_MESSAGE_SCHEMA = cv.make_entity_service_schema(
{vol.Optional(ATTR_TAG): cv.string}
)
@callback
def async_setup_services(hass: HomeAssistant) -> None:
@@ -80,3 +85,11 @@ def async_setup_services(hass: HomeAssistant) -> None:
schema=SERVICE_SEND_MESSAGE_SCHEMA,
func="send_push_notification",
)
service.async_register_platform_entity_service(
hass,
DOMAIN,
SERVICE_DISMISS_MESSAGE,
entity_domain=NOTIFY_DOMAIN,
schema=SERVICE_DISMISS_MESSAGE_SCHEMA,
func="dismiss_notification",
)

View File

@@ -44,7 +44,7 @@ send_message:
text:
type: url
example: /static/images/image.jpg
tag:
tag: &tag
required: false
selector:
text:
@@ -142,3 +142,10 @@ send_message:
selector:
object:
example: "{'customKey': 'customValue'}"
dismiss_message:
target:
entity:
domain: notify
integration: html5
fields:
tag: *tag

View File

@@ -49,6 +49,10 @@
}
},
"issues": {
"deprecated_dismiss_action": {
"description": "The action `{action}` is deprecated and will be removed in a future release.\n\nPlease update your automations and scripts to use the notify entities with the `{new_action}` action instead.",
"title": "[%key:component::html5::issues::deprecated_notify_action::title%]"
},
"deprecated_notify_action": {
"description": "The action `{action}` is deprecated and will be removed in a future release.\n\nPlease update your automations and scripts to use the notify entities with the `notify.send_message` or `html5.send_message` actions instead.",
"title": "Detected use of deprecated action {action}"
@@ -101,6 +105,16 @@
},
"name": "Dismiss"
},
"dismiss_message": {
"description": "Dismisses one or more HTML5 notifications.",
"fields": {
"tag": {
"description": "The tag of the notifications to dismiss. If not specified, all notifications will be dismissed.",
"name": "Tag"
}
},
"name": "Dismiss message"
},
"send_message": {
"description": "Sends a message via HTML5 Push Notifications",
"fields": {

View File

@@ -28,8 +28,10 @@ from homeassistant.components.html5.const import (
ATTR_TTL,
ATTR_URGENCY,
ATTR_VIBRATE,
SERVICE_DISMISS,
)
from homeassistant.components.html5.notify import ATTR_ACTION, DEFAULT_TTL
from homeassistant.components.html5.notify import ATTR_ACTION, ATTR_DISMISS, DEFAULT_TTL
from homeassistant.components.html5.services import SERVICE_DISMISS_MESSAGE
from homeassistant.components.notify import (
ATTR_DATA,
ATTR_MESSAGE,
@@ -1114,11 +1116,32 @@ async def test_html5_send_message(
@pytest.mark.parametrize(
("target", "issue_id"),
("domain", "service", "service_data", "issue_id"),
[
(["my-desktop"], "deprecated_notify_action_notify.html5_my_desktop"),
(None, "deprecated_notify_action_notify.html5"),
(["my-desktop", "my-phone"], "deprecated_notify_action_notify.html5"),
(
NOTIFY_DOMAIN,
"html5_my_desktop",
{ATTR_MESSAGE: "Hello", ATTR_TARGET: ["my-desktop"]},
"deprecated_notify_action_notify.html5_my_desktop",
),
(
NOTIFY_DOMAIN,
DOMAIN,
{ATTR_MESSAGE: "Hello"},
"deprecated_notify_action_notify.html5",
),
(
NOTIFY_DOMAIN,
DOMAIN,
{ATTR_MESSAGE: "Hello", ATTR_TARGET: ["my-desktop", "my-phone"]},
"deprecated_notify_action_notify.html5",
),
(
DOMAIN,
SERVICE_DISMISS,
{},
"deprecated_dismiss_action",
),
],
)
@pytest.mark.usefixtures("mock_wp", "mock_jwt", "mock_vapid", "mock_uuid")
@@ -1127,7 +1150,9 @@ async def test_deprecation_action_call(
config_entry: MockConfigEntry,
load_config: MagicMock,
issue_registry: ir.IssueRegistry,
target: list[str] | None,
domain: str,
service: str,
service_data: dict[str, Any] | None,
issue_id: str,
) -> None:
"""Test deprecation action call."""
@@ -1143,9 +1168,9 @@ async def test_deprecation_action_call(
assert config_entry.state is ConfigEntryState.LOADED
await hass.services.async_call(
NOTIFY_DOMAIN,
DOMAIN,
{ATTR_MESSAGE: "Hello", ATTR_TARGET: target},
domain,
service,
service_data,
blocking=True,
)
@@ -1153,3 +1178,55 @@ async def test_deprecation_action_call(
domain=DOMAIN,
issue_id=issue_id,
)
@pytest.mark.parametrize(
("service_data", "expected_payload"),
[
(
{ATTR_TAG: "message-group-1"},
{ATTR_DISMISS: True, ATTR_TAG: "message-group-1"},
),
(
{},
{ATTR_DISMISS: True, ATTR_TAG: ""},
),
],
)
@pytest.mark.usefixtures("mock_jwt", "mock_vapid", "mock_uuid")
@pytest.mark.freeze_time("2009-02-13T23:31:30.000Z")
async def test_html5_dismiss_message(
hass: HomeAssistant,
config_entry: MockConfigEntry,
webpush_async: AsyncMock,
load_config: MagicMock,
service_data: dict[str, Any],
expected_payload: dict[str, Any],
) -> None:
"""Test dismissing a message via html5.dismiss_message action."""
load_config.return_value = {"my-desktop": SUBSCRIPTION_1}
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED
await hass.services.async_call(
DOMAIN,
SERVICE_DISMISS_MESSAGE,
{
ATTR_ENTITY_ID: "notify.my_desktop",
**service_data,
},
blocking=True,
)
webpush_async.assert_awaited_once()
assert webpush_async.await_args
_, payload, _, _ = webpush_async.await_args.args
assert json.loads(payload) == {
"timestamp": 1234567890000,
"data": {"jwt": "JWT"},
**expected_payload,
}