-
-
Notifications
You must be signed in to change notification settings - Fork 32.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add device action to mobile app to notify (#43814)
- Loading branch information
Showing
17 changed files
with
263 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
"""Provides device actions for Mobile App.""" | ||
from typing import List, Optional | ||
|
||
import voluptuous as vol | ||
|
||
from homeassistant.components import notify | ||
from homeassistant.components.device_automation import InvalidDeviceAutomationConfig | ||
from homeassistant.const import CONF_DEVICE_ID, CONF_DOMAIN, CONF_TYPE | ||
from homeassistant.core import Context, HomeAssistant | ||
from homeassistant.helpers import config_validation as cv, template | ||
|
||
from .const import DOMAIN | ||
from .util import get_notify_service, supports_push, webhook_id_from_device_id | ||
|
||
ACTION_SCHEMA = cv.DEVICE_ACTION_BASE_SCHEMA.extend( | ||
{ | ||
vol.Required(CONF_TYPE): "notify", | ||
vol.Required(notify.ATTR_MESSAGE): cv.template, | ||
vol.Optional(notify.ATTR_TITLE): cv.template, | ||
vol.Optional(notify.ATTR_DATA): cv.template_complex, | ||
} | ||
) | ||
|
||
|
||
async def async_get_actions(hass: HomeAssistant, device_id: str) -> List[dict]: | ||
"""List device actions for Mobile App devices.""" | ||
webhook_id = webhook_id_from_device_id(hass, device_id) | ||
|
||
if webhook_id is None or not supports_push(hass, webhook_id): | ||
return [] | ||
|
||
return [{CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_TYPE: "notify"}] | ||
|
||
|
||
async def async_call_action_from_config( | ||
hass: HomeAssistant, config: dict, variables: dict, context: Optional[Context] | ||
) -> None: | ||
"""Execute a device action.""" | ||
webhook_id = webhook_id_from_device_id(hass, config[CONF_DEVICE_ID]) | ||
|
||
if webhook_id is None: | ||
raise InvalidDeviceAutomationConfig( | ||
"Unable to resolve webhook ID from the device ID" | ||
) | ||
|
||
service_name = get_notify_service(hass, webhook_id) | ||
|
||
if service_name is None: | ||
raise InvalidDeviceAutomationConfig( | ||
"Unable to find notify service for webhook ID" | ||
) | ||
|
||
service_data = {notify.ATTR_TARGET: webhook_id} | ||
|
||
# Render it here because we have access to variables here. | ||
for key in (notify.ATTR_MESSAGE, notify.ATTR_TITLE, notify.ATTR_DATA): | ||
if key not in config: | ||
continue | ||
|
||
value_template = config[key] | ||
template.attach(hass, value_template) | ||
|
||
try: | ||
service_data[key] = template.render_complex(value_template, variables) | ||
except template.TemplateError as err: | ||
raise InvalidDeviceAutomationConfig( | ||
f"Error rendering {key}: {err}" | ||
) from err | ||
|
||
await hass.services.async_call( | ||
notify.DOMAIN, service_name, service_data, blocking=True, context=context | ||
) | ||
|
||
|
||
async def async_get_action_capabilities(hass, config): | ||
"""List action capabilities.""" | ||
if config[CONF_TYPE] != "notify": | ||
return {} | ||
|
||
return { | ||
"extra_fields": vol.Schema( | ||
{ | ||
vol.Required(notify.ATTR_MESSAGE): str, | ||
vol.Optional(notify.ATTR_TITLE): str, | ||
} | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
"""Mobile app utility functions.""" | ||
from typing import TYPE_CHECKING, Optional | ||
|
||
from homeassistant.core import callback | ||
|
||
from .const import ( | ||
ATTR_APP_DATA, | ||
ATTR_PUSH_TOKEN, | ||
ATTR_PUSH_URL, | ||
DATA_CONFIG_ENTRIES, | ||
DATA_DEVICES, | ||
DATA_NOTIFY, | ||
DOMAIN, | ||
) | ||
|
||
if TYPE_CHECKING: | ||
from .notify import MobileAppNotificationService | ||
|
||
|
||
@callback | ||
def webhook_id_from_device_id(hass, device_id: str) -> Optional[str]: | ||
"""Get webhook ID from device ID.""" | ||
for cur_webhook_id, cur_device in hass.data[DOMAIN][DATA_DEVICES].items(): | ||
if cur_device.id == device_id: | ||
return cur_webhook_id | ||
|
||
return None | ||
|
||
|
||
@callback | ||
def supports_push(hass, webhook_id: str) -> bool: | ||
"""Return if push notifications is supported.""" | ||
config_entry = hass.data[DOMAIN][DATA_CONFIG_ENTRIES][webhook_id] | ||
app_data = config_entry.data[ATTR_APP_DATA] | ||
return ATTR_PUSH_TOKEN in app_data and ATTR_PUSH_URL in app_data | ||
|
||
|
||
@callback | ||
def get_notify_service(hass, webhook_id: str) -> Optional[str]: | ||
"""Return the notify service for this webhook ID.""" | ||
notify_service: "MobileAppNotificationService" = hass.data[DOMAIN][DATA_NOTIFY] | ||
|
||
for target_service, target_webhook_id in notify_service.registered_targets.items(): | ||
if target_webhook_id == webhook_id: | ||
return target_service | ||
|
||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
script/scaffold/templates/device_action/tests/test_device_action.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
script/scaffold/templates/device_condition/integration/device_condition.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
script/scaffold/templates/device_condition/tests/test_device_condition.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
script/scaffold/templates/device_trigger/tests/test_device_trigger.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.