1 """Notifications for Android TV notification service."""
3 from __future__
import annotations
5 from io
import BufferedReader
9 from notifications_android_tv
import Notifications
11 from requests.auth
import HTTPBasicAuth, HTTPDigestAuth
12 import voluptuous
as vol
18 BaseNotificationService,
32 ATTR_ICON_AUTH_DIGEST,
39 ATTR_IMAGE_AUTH_DIGEST,
51 _LOGGER = logging.getLogger(__name__)
57 discovery_info: DiscoveryInfoType |
None =
None,
58 ) -> NFAndroidTVNotificationService |
None:
59 """Get the NFAndroidTV notification service."""
60 if discovery_info
is None:
62 notify = await hass.async_add_executor_job(Notifications, discovery_info[CONF_HOST])
65 hass.config.is_allowed_path,
70 """Notification service for Notifications for Android TV."""
74 notify: Notifications,
77 """Initialize the service."""
82 """Send a message to a Android TV device."""
83 data: dict |
None = kwargs.get(ATTR_DATA)
84 title = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT)
94 if ATTR_DURATION
in data:
97 data.get(ATTR_DURATION, Notifications.DEFAULT_DURATION)
101 "Invalid duration-value: %s", data.get(ATTR_DURATION)
103 if ATTR_FONTSIZE
in data:
104 if data.get(ATTR_FONTSIZE)
in Notifications.FONTSIZES:
105 fontsize = data.get(ATTR_FONTSIZE)
108 "Invalid fontsize-value: %s", data.get(ATTR_FONTSIZE)
110 if ATTR_POSITION
in data:
111 if data.get(ATTR_POSITION)
in Notifications.POSITIONS:
112 position = data.get(ATTR_POSITION)
115 "Invalid position-value: %s", data.get(ATTR_POSITION)
117 if ATTR_TRANSPARENCY
in data:
118 if data.get(ATTR_TRANSPARENCY)
in Notifications.TRANSPARENCIES:
119 transparency = data.get(ATTR_TRANSPARENCY)
122 "Invalid transparency-value: %s",
123 data.get(ATTR_TRANSPARENCY),
125 if ATTR_COLOR
in data:
126 if data.get(ATTR_COLOR)
in Notifications.BKG_COLORS:
127 bkgcolor = data.get(ATTR_COLOR)
129 _LOGGER.warning(
"Invalid color-value: %s", data.get(ATTR_COLOR))
130 if ATTR_INTERRUPT
in data:
132 interrupt = cv.boolean(data.get(ATTR_INTERRUPT))
135 "Invalid interrupt-value: %s", data.get(ATTR_INTERRUPT)
137 if imagedata := data.get(ATTR_IMAGE):
138 if isinstance(imagedata, str):
141 if imagedata.startswith(
"http")
142 else self.
load_fileload_file(local_path=imagedata)
144 elif isinstance(imagedata, dict):
146 url=imagedata.get(ATTR_IMAGE_URL),
147 local_path=imagedata.get(ATTR_IMAGE_PATH),
148 username=imagedata.get(ATTR_IMAGE_USERNAME),
149 password=imagedata.get(ATTR_IMAGE_PASSWORD),
150 auth=imagedata.get(ATTR_IMAGE_AUTH),
154 "Invalid image provided",
155 translation_domain=DOMAIN,
156 translation_key=
"invalid_notification_image",
157 translation_placeholders={
"type": type(imagedata).__name__},
159 if icondata := data.get(ATTR_ICON):
160 if isinstance(icondata, str):
163 if icondata.startswith(
"http")
164 else self.
load_fileload_file(local_path=icondata)
166 elif isinstance(icondata, dict):
168 url=icondata.get(ATTR_ICON_URL),
169 local_path=icondata.get(ATTR_ICON_PATH),
170 username=icondata.get(ATTR_ICON_USERNAME),
171 password=icondata.get(ATTR_ICON_PASSWORD),
172 auth=icondata.get(ATTR_ICON_AUTH),
176 "Invalid Icon provided",
177 translation_domain=DOMAIN,
178 translation_key=
"invalid_notification_icon",
179 translation_placeholders={
"type": type(icondata).__name__},
188 transparency=transparency,
191 image_file=image_file,
196 url: str |
None =
None,
197 local_path: str |
None =
None,
198 username: str |
None =
None,
199 password: str |
None =
None,
200 auth: str |
None =
None,
201 ) -> BufferedReader | bytes |
None:
202 """Load image/document/etc from a local path or URL."""
206 if username
is not None and password
is not None:
208 auth_: HTTPDigestAuth | HTTPBasicAuth
209 if auth
in (ATTR_IMAGE_AUTH_DIGEST, ATTR_ICON_AUTH_DIGEST):
210 auth_ = HTTPDigestAuth(username, password)
212 auth_ = HTTPBasicAuth(username, password)
214 req = requests.get(url, auth=auth_, timeout=DEFAULT_TIMEOUT)
217 req = requests.get(url, timeout=DEFAULT_TIMEOUT)
220 if local_path
is not None:
223 return open(local_path,
"rb")
224 _LOGGER.warning(
"'%s' is not secure to load data from!", local_path)
226 _LOGGER.warning(
"Neither URL nor local path found in params!")
228 except OSError
as error:
229 _LOGGER.error(
"Can't load from url or local path: %s", error)
None send_message(self, str message, **Any kwargs)
BufferedReader|bytes|None load_file(self, str|None url=None, str|None local_path=None, str|None username=None, str|None password=None, str|None auth=None)
None __init__(self, Notifications notify, Any is_allowed_path)
NFAndroidTVNotificationService|None async_get_service(HomeAssistant hass, ConfigType config, DiscoveryInfoType|None discovery_info=None)
None open(self, **Any kwargs)