Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow reconfiguring via options #2319

Merged
merged 37 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5fe6c02
Add files via upload
danielbrunt57 Jul 15, 2024
32285af
Delete en.json
danielbrunt57 Jul 15, 2024
fd5bf3a
Delete config_flow.py
danielbrunt57 Jul 15, 2024
8019180
Delete const.py
danielbrunt57 Jul 15, 2024
8d6b7ee
Delete media_player.py
danielbrunt57 Jul 15, 2024
31d8516
Delete strings.json
danielbrunt57 Jul 15, 2024
d04819c
Add files via upload
danielbrunt57 Jul 15, 2024
15a125b
Add files via upload
danielbrunt57 Jul 15, 2024
acda798
Update __init__.py
danielbrunt57 Jul 16, 2024
ab3ccb6
Update media_player.py
danielbrunt57 Jul 16, 2024
05a21d3
Merge branch 'dev' into dev
danielbrunt57 Jul 16, 2024
cafe9c7
Update services.yaml
danielbrunt57 Jul 16, 2024
c677777
Delete __init__.py
danielbrunt57 Jul 16, 2024
34f81ad
Update hacs.json
danielbrunt57 Jul 16, 2024
cd38d1a
Update hacs.json
danielbrunt57 Jul 16, 2024
1a557d8
Update hacs.json
danielbrunt57 Jul 17, 2024
5000271
Update config_flow.py
danielbrunt57 Jul 17, 2024
33ef1c2
Update config_flow.py
danielbrunt57 Jul 17, 2024
8943bc8
Update strings.json
danielbrunt57 Jul 17, 2024
451a777
Update en.json
danielbrunt57 Jul 17, 2024
cb994a8
Add files via upload
danielbrunt57 Jul 17, 2024
3de867c
Add files via upload
danielbrunt57 Jul 17, 2024
9006d34
Update strings.json
danielbrunt57 Jul 17, 2024
c1ed092
Update en.json
danielbrunt57 Jul 17, 2024
6eec1e3
Add files via upload
danielbrunt57 Jul 17, 2024
e68c8e5
Add files via upload
danielbrunt57 Jul 17, 2024
4e9e23e
Update config_flow.py
danielbrunt57 Jul 17, 2024
854b2a3
Add files via upload
danielbrunt57 Jul 17, 2024
c241758
Add files via upload
danielbrunt57 Jul 17, 2024
e93f83a
Merge branch 'dev' into dev
alandtse Jul 18, 2024
ce1256e
Merge branch 'dev' into dev
alandtse Jul 18, 2024
b68f83a
Merge branch 'dev' into dev
alandtse Jul 18, 2024
984a671
Merge branch 'dev' into dev
alandtse Jul 18, 2024
8f54ee0
Merge branch 'dev' into dev
alandtse Jul 18, 2024
af4f282
build: bump pre-commit deps
alandtse Jul 18, 2024
3277efc
style: run pre-commit
alandtse Jul 18, 2024
d7a9a38
style: auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 140 additions & 60 deletions custom_components/alexa_media/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from homeassistant.core import callback
from homeassistant.data_entry_flow import UnknownFlow
from homeassistant.exceptions import Unauthorized
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.network import NoURLAvailableError, get_url
from homeassistant.util import slugify
import httpx
Expand All @@ -55,9 +56,11 @@
CONF_SECURITYCODE,
CONF_TOTP_REGISTER,
DATA_ALEXAMEDIA,
DEFAULT_EXTENDED_ENTITY_DISCOVERY,
DEFAULT_PUBLIC_URL,
DEFAULT_QUEUE_DELAY,
DEFAULT_SCAN_DELAY,
DEFAULT_EXTENDED_ENTITY_DISCOVERY,
DEFAULT_DEBUG,
DOMAIN,
ISSUE_URL,
STARTUP,
Expand Down Expand Up @@ -111,15 +114,18 @@ def __init__(self):
self.proxy_schema = None
self.data_schema = OrderedDict(
[
(vol.Required(CONF_URL, default="amazon.com"), str),
(vol.Required(CONF_HASS_URL), str),
(vol.Required(CONF_EMAIL), str),
(vol.Required(CONF_PASSWORD), str),
(vol.Required(CONF_URL, default="amazon.com"), str),
(vol.Optional(CONF_SECURITYCODE), str),
(vol.Optional(CONF_OTPSECRET), str),
(vol.Optional(CONF_DEBUG, default=False), bool),
(vol.Optional(CONF_SECURITYCODE), str),
(vol.Optional(CONF_INCLUDE_DEVICES, default=""), str),
(vol.Optional(CONF_EXCLUDE_DEVICES, default=""), str),
(vol.Optional(CONF_SCAN_INTERVAL, default=60), int),
(vol.Optional(CONF_QUEUE_DELAY, default=1.5), float),
(vol.Optional(CONF_EXTENDED_ENTITY_DISCOVERY, default=False), bool),
(vol.Optional(CONF_DEBUG, default=False), bool),
]
)
self.totp_register = OrderedDict(
Expand All @@ -143,40 +149,39 @@ async def async_step_user(self, user_input=None):
hass_url = ""
self.proxy_schema = OrderedDict(
[
(
vol.Required(CONF_EMAIL, default=self.config.get(CONF_EMAIL, "")),
str,
),
(
vol.Required(
CONF_PASSWORD, default=self.config.get(CONF_PASSWORD, "")
CONF_URL,
default=self.config.get(CONF_URL, "amazon.com")
),
str,
),
(
vol.Required(
CONF_URL, default=self.config.get(CONF_URL, "amazon.com")
),
CONF_EMAIL,
default=self.config.get(CONF_EMAIL, "")),
str,
),
(
vol.Required(
CONF_HASS_URL,
default=self.config.get(CONF_HASS_URL, hass_url),
CONF_PASSWORD,
default=self.config.get(CONF_PASSWORD, "")
),
str,
),
(
vol.Optional(
CONF_OTPSECRET, default=self.config.get(CONF_OTPSECRET, "")
CONF_OTPSECRET,
default=self.config.get(CONF_OTPSECRET, "")
),
str,
),
(
vol.Optional(
CONF_DEBUG, default=self.config.get(CONF_DEBUG, False)
CONF_HASS_URL,
default=self.config.get(CONF_HASS_URL, ""),
),
bool,
str,
),
(
vol.Optional(
Expand All @@ -195,10 +200,31 @@ async def async_step_user(self, user_input=None):
(
vol.Optional(
CONF_SCAN_INTERVAL,
default=self.config.get(CONF_SCAN_INTERVAL, 60),
default=self.config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_DELAY),
),
int,
),
(
vol.Optional(
CONF_QUEUE_DELAY,
default=self.config.get(CONF_QUEUE_DELAY, DEFAULT_QUEUE_DELAY),
),
float,
),
(
vol.Optional(
CONF_EXTENDED_ENTITY_DISCOVERY,
default=self.config.get(CONF_EXTENDED_ENTITY_DISCOVERY, DEFAULT_EXTENDED_ENTITY_DISCOVERY)
),
bool,
),
(
vol.Optional(
CONF_DEBUG,
default=self.config.get(CONF_DEBUG, DEFAULT_DEBUG)
),
bool,
),
]
)
if not user_input:
Expand Down Expand Up @@ -570,8 +596,11 @@ async def _test_login(self):
self.config.pop("reauth")
if self.config.get(CONF_SECURITYCODE):
self.config.pop(CONF_SECURITYCODE)

# ### Alan, why is this being done? ###
danielbrunt57 marked this conversation as resolved.
Show resolved Hide resolved
if self.config.get("hass_url"):
self.config.pop("hass_url")

self.config[CONF_OAUTH] = {
"access_token": login.access_token,
"refresh_token": login.refresh_token,
Expand Down Expand Up @@ -691,8 +720,8 @@ def _save_user_input_to_config(self, user_input=None) -> None:
"""
if user_input is None:
return
if CONF_HASS_URL in user_input:
self.config[CONF_HASS_URL] = user_input[CONF_HASS_URL]
if CONF_URL in user_input:
self.config[CONF_URL] = user_input[CONF_URL]
self.securitycode = user_input.get(CONF_SECURITYCODE)
if self.securitycode is not None:
self.config[CONF_SECURITYCODE] = self.securitycode
Expand All @@ -709,16 +738,18 @@ def _save_user_input_to_config(self, user_input=None) -> None:
self.config[CONF_EMAIL] = user_input[CONF_EMAIL]
if CONF_PASSWORD in user_input:
self.config[CONF_PASSWORD] = user_input[CONF_PASSWORD]
if CONF_URL in user_input:
self.config[CONF_URL] = user_input[CONF_URL]
if CONF_DEBUG in user_input:
self.config[CONF_DEBUG] = user_input[CONF_DEBUG]
if CONF_HASS_URL in user_input:
self.config[CONF_HASS_URL] = user_input[CONF_HASS_URL]
if CONF_SCAN_INTERVAL in user_input:
self.config[CONF_SCAN_INTERVAL] = (
user_input[CONF_SCAN_INTERVAL]
if not isinstance(user_input[CONF_SCAN_INTERVAL], timedelta)
else user_input[CONF_SCAN_INTERVAL].total_seconds()
)
if CONF_QUEUE_DELAY in user_input:
self.config[CONF_QUEUE_DELAY] = (
user_input[CONF_QUEUE_DELAY]
)
if CONF_INCLUDE_DEVICES in user_input:
if isinstance(user_input[CONF_INCLUDE_DEVICES], list):
self.config[CONF_INCLUDE_DEVICES] = (
Expand All @@ -737,29 +768,38 @@ def _save_user_input_to_config(self, user_input=None) -> None:
)
else:
self.config[CONF_EXCLUDE_DEVICES] = user_input[CONF_EXCLUDE_DEVICES]
if CONF_EXTENDED_ENTITY_DISCOVERY in user_input:
self.config[CONF_EXTENDED_ENTITY_DISCOVERY] = user_input[CONF_EXTENDED_ENTITY_DISCOVERY]
if CONF_DEBUG in user_input:
self.config[CONF_DEBUG] = user_input[CONF_DEBUG]

def _update_schema_defaults(self) -> Any:
new_schema = self._update_ord_dict(
self.data_schema,
{
vol.Required(CONF_EMAIL, default=self.config.get(CONF_EMAIL, "")): str,
vol.Required(
CONF_PASSWORD, default=self.config.get(CONF_PASSWORD, "")
CONF_URL,
default=self.config.get(CONF_URL, "amazon.com")
): str,
vol.Optional(
vol.Required(CONF_EMAIL,
default=self.config.get(CONF_EMAIL, "")
): str,
vol.Required(
CONF_PASSWORD,
default=self.config.get(CONF_PASSWORD, "")
): str,
vol.Required(
CONF_SECURITYCODE,
default=self.securitycode if self.securitycode else "",
): str,
vol.Optional(
vol.Required(
CONF_OTPSECRET,
default=self.config.get(CONF_OTPSECRET, ""),
): str,
vol.Required(
CONF_URL, default=self.config.get(CONF_URL, "amazon.com")
): str,
vol.Optional(
CONF_DEBUG, default=bool(self.config.get(CONF_DEBUG, False))
): bool,
# vol.Required(
# CONF_HASS_URL,
# default=self.config_entry.options.get(CONF_HASS_URL, ""),
danielbrunt57 marked this conversation as resolved.
Show resolved Hide resolved
# ): str,
vol.Optional(
CONF_INCLUDE_DEVICES,
default=self.config.get(CONF_INCLUDE_DEVICES, ""),
Expand All @@ -769,8 +809,24 @@ def _update_schema_defaults(self) -> Any:
default=self.config.get(CONF_EXCLUDE_DEVICES, ""),
): str,
vol.Optional(
CONF_SCAN_INTERVAL, default=self.config.get(CONF_SCAN_INTERVAL, 60)
CONF_SCAN_INTERVAL,
default=self.config.get(CONF_SCAN_INTERVAL, 60)
): int,
vol.Optional(
CONF_QUEUE_DELAY,
default=self.config_entry.options.get(CONF_QUEUE_DELAY, 1.5
),
):float,
vol.Optional(
CONF_EXTENDED_ENTITY_DISCOVERY,
default=self.config_entry.options.get(
CONF_EXTENDED_ENTITY_DISCOVERY,
DEFAULT_EXTENDED_ENTITY_DISCOVERY,
),
): bool,
vol.Optional(
CONF_DEBUG, default=bool(self.config.get(CONF_DEBUG, False))
): bool,
},
)
return new_schema
Expand All @@ -781,44 +837,68 @@ def async_get_options_flow(config_entry):
"""Get the options flow for this handler."""
return OptionsFlowHandler(config_entry)


class OptionsFlowHandler(config_entries.OptionsFlow):
"""Handle a option flow for Alexa Media."""

def __init__(self, config_entry: config_entries.ConfigEntry):
def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
"""Initialize options flow."""
self.config_entry = config_entry

async def async_step_init(self, user_input=None):
"""Handle options flow."""
if user_input is not None:
return self.async_create_entry(title="", data=user_input)
"""Preserve these parameters"""
if CONF_URL in self.config_entry.data:
user_input[CONF_URL] = self.config_entry.data[CONF_URL]
if CONF_EMAIL in self.config_entry.data:
user_input[CONF_EMAIL] = self.config_entry.data[CONF_EMAIL]
if CONF_PASSWORD in self.config_entry.data:
user_input[CONF_PASSWORD] = self.config_entry.data[CONF_PASSWORD]
if CONF_SECURITYCODE in self.config_entry.data:
user_input[CONF_SECURITYCODE] = self.config_entry.data[CONF_SECURITYCODE]
if CONF_OTPSECRET in self.config_entry.data:
user_input[CONF_OTPSECRET] = self.config_entry.data[CONF_OTPSECRET]

self.hass.config_entries.async_update_entry(
self.config_entry, data=user_input, options=self.config_entry.options
)
return self.async_create_entry(title="", data={})

data_schema = vol.Schema(
{
vol.Optional(
CONF_QUEUE_DELAY,
default=self.config_entry.options.get(
CONF_QUEUE_DELAY, DEFAULT_QUEUE_DELAY
),
): vol.All(vol.Coerce(float), vol.Clamp(min=0)),
vol.Optional(
CONF_PUBLIC_URL,
default=self.config_entry.options.get(
CONF_PUBLIC_URL, DEFAULT_PUBLIC_URL
),
): str,
vol.Required(
CONF_EXTENDED_ENTITY_DISCOVERY,
default=self.config_entry.options.get(
return self.async_show_form(
step_id="init",
data_schema=vol.Schema(
{
# vol.Optional(
# CONF_HASS_URL,
# default=self.config_entry.data[CONF_HASS_URL],
# ): cv.string,
vol.Optional(
CONF_INCLUDE_DEVICES,
default=self.config_entry.data[CONF_INCLUDE_DEVICES],
): cv.string,
vol.Optional(
CONF_EXCLUDE_DEVICES,
default=self.config_entry.data[CONF_EXCLUDE_DEVICES],
): cv.string,
vol.Optional(
CONF_SCAN_INTERVAL,
default=self.config_entry.data[CONF_SCAN_INTERVAL],
): vol.All(vol.Coerce(int), vol.Range(min=0, max=1800)),
vol.Optional(
CONF_QUEUE_DELAY,
default=self.config_entry.data[CONF_QUEUE_DELAY],
): vol.All(vol.Coerce(float), vol.Range(min=0.5, max=5.0)),
vol.Optional(
CONF_EXTENDED_ENTITY_DISCOVERY,
DEFAULT_EXTENDED_ENTITY_DISCOVERY,
),
): bool,
}
default=self.config_entry.data[CONF_EXTENDED_ENTITY_DISCOVERY],
): cv.boolean,
vol.Optional(
CONF_DEBUG,
default=self.config_entry.data[CONF_DEBUG],
): cv.boolean,
}
),
)
return self.async_show_form(step_id="init", data_schema=data_schema)


class AlexaMediaAuthorizationCallbackView(HomeAssistantView):
"""Handle callback from external auth."""
Expand Down
4 changes: 3 additions & 1 deletion custom_components/alexa_media/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@

EXCEPTION_TEMPLATE = "An exception of type {0} occurred. Arguments:\n{1!r}"

DEFAULT_EXTENDED_ENTITY_DISCOVERY = False
DEFAULT_SCAN_DELAY = 60
DEFAULT_QUEUE_DELAY = 1.5
DEFAULT_PUBLIC_URL = ""
DEFAULT_EXTENDED_ENTITY_DISCOVERY = False
DEFAULT_DEBUG = False
SERVICE_CLEAR_HISTORY = "clear_history"
SERVICE_UPDATE_LAST_CALLED = "update_last_called"
SERVICE_FORCE_LOGOUT = "force_logout"
Expand Down
17 changes: 0 additions & 17 deletions custom_components/alexa_media/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,6 @@ update_last_called:
# Example value that can be passed for this field
example: "[email protected]"

clear_history:
# Description of the service
description: Clear last entries from Alexa Voice history for each Alexa account.
# Different fields that your service accepts
fields:
# Key of the field
email:
# Description of the field
description: List of Alexa accounts to update. If empty, will delete from all known accounts.
# Example value that can be passed for this field
example: "[email protected]"
entries:
# Description of the field
description: Number of entries to clear from 1 to 50. If empty, clear 50.
# Example value that can be passed for this field
example: 50

force_logout:
# Description of the service
description: Force logout of Alexa Login account and deletion of .pickle. Intended for debugging use.
Expand Down
Loading
Loading