Skip to content

Commit

Permalink
1.1.0b0
Browse files Browse the repository at this point in the history
Bump pyfamilysafety to 0.1.0
Removes the refresh_token parameter during setup
Sets response_url as required during setup
Change async_setup_entry during init to only grab refresh token
Add options flow handler
  • Loading branch information
pantherale0 committed Sep 17, 2023
1 parent 4d712d0 commit d9fc0c6
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 36 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ __pycache__

# misc
.coverage
.vscode
coverage.xml


Expand Down
23 changes: 23 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
// Example of attaching to local debug server
"name": "Python: Attach Local",
"type": "python",
"request": "attach",
"justMyCode": false,
"port": 5678,
"host": "127.0.0.1", // same as the browser that was opened by Docker Desktop.
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
]
}
]
}
1 change: 1 addition & 0 deletions config/configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ logger:
default: info
logs:
custom_components.family_safety: debug
pyfamilysafety: debug

# Enable VSCode debugging
debugpy:
Expand Down
15 changes: 4 additions & 11 deletions custom_components/family_safety/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data.setdefault(DOMAIN, {})
_LOGGER.debug("Got request to setup entry.")
try:
familysafety = None
if len(entry.data["refresh_token"]) > 0:
familysafety = await FamilySafety.create(
token=entry.data["refresh_token"],
use_refresh_token=True
)
else:
familysafety = await FamilySafety.create(
token=entry.data["response_url"],
use_refresh_token=False
)
familysafety = await FamilySafety.create(
token=entry.data["refresh_token"],
use_refresh_token=True
)
_LOGGER.debug("Login successful, setting up coordinator.")
hass.data[DOMAIN][entry.entry_id] = FamilySafetyCoordinator(
hass,
Expand Down
77 changes: 56 additions & 21 deletions custom_components/family_safety/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import logging
from typing import Any

from pyfamilysafety import FamilySafetyAPI
from pyfamilysafety.authenticator import Authenticator
from pyfamilysafety.exceptions import HttpException
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.exceptions import HomeAssistantError

Expand All @@ -18,45 +18,46 @@

CONFIG_SCHEMA = vol.Schema(
{
vol.Optional("refresh_token"): str,
vol.Optional("response_url"): str,
vol.Required("response_url"): str,
vol.Required("update_interval", default=60): int
}
)

async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str, Any]:
"""Validate the input."""
familysafety: FamilySafetyAPI = None
auth: Authenticator = None
try:
_LOGGER.debug("Config flow received -> test credentials")
if len(data["refresh_token"])>0:
familysafety = await FamilySafetyAPI.create(
token=data["refresh_token"],
use_refresh_token=True
)
else:
familysafety = await FamilySafetyAPI.create(
token=data["response_url"],
use_refresh_token=False
)
auth = await Authenticator.create(
token=data["response_url"],
use_refresh_token=False
)
except HttpException as err:
_LOGGER.error(err)
raise InvalidAuth from err
except Exception as err:
_LOGGER.error(err)
raise CannotConnect from err

_LOGGER.debug("Authentication success, returning refresh_token.")
_LOGGER.debug("Authentication success, expiry time %s, returning refresh_token.", auth.expires)
return {
"title": "Microsoft Family Safety",
"refresh_token": familysafety.authenticator.refresh_token
"refresh_token": auth.refresh_token
}

class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow."""

VERSION = 1

@staticmethod
@callback
def async_get_options_flow(
config_entry: config_entries.ConfigEntry
) -> config_entries.OptionsFlow:
"""Create the options flow."""
return OptionsFlow(config_entry)

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
Expand All @@ -65,24 +66,58 @@ async def async_step_user(
if user_input is not None:
try:
info = await validate_input(self.hass, user_input)
user_input["refresh_token"] = info["refresh_token"]
return self.async_create_entry(title=info["title"], data=user_input)
except InvalidAuth as err:
_LOGGER.warning("Invalid authentication received: %s", err)
errors["base"] = "invalid_auth"
except CannotConnect as err:
_LOGGER.warning("Cannot connect: %s", err)
errors["base"] = "cannot_connect"
except Exception as err:
_LOGGER.error(err)
errors["base"] = "unknown"
else:
user_input["response_url"] = ""
user_input["refresh_token"] = info["refresh_token"]
return self.async_create_entry(title=info["title"], data=user_input)

return self.async_show_form(
step_id="user",
data_schema=CONFIG_SCHEMA,
errors=errors
)

class OptionsFlow(config_entries.OptionsFlow):
"""An options flow for HASS."""
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: dict[str, Any] | None = None
) -> config_entries.FlowResult:
"""Initial step."""
if user_input is not None:
return self.async_create_entry(
title=self.config_entry.title,
data={
"refresh_token": user_input["refresh_token"],
"update_interval": user_input["update_interval"]
}
)

update_interval = self.config_entry.data["update_interval"]
if self.config_entry.options:
update_interval = self.config_entry.options.get("update_interval")

return self.async_show_form(
step_id="init",
data_schema=vol.Schema(
{
vol.Required("update_interval", default=update_interval): int,
vol.Required("refresh_token",
default=self.config_entry.data["refresh_token"]): str
}
)
)

class CannotConnect(HomeAssistantError):
"""Error to indicate we cannot connect."""

Expand Down
2 changes: 1 addition & 1 deletion custom_components/family_safety/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

NAME = "Microsoft Family Safety"
DOMAIN = "family_safety"
VERSION = "0.0.0"
VERSION = "1.1.0b0"

DEFAULT_OVERRIDE_ENTITIES = [OverrideTarget.MOBILE,
OverrideTarget.WINDOWS,
Expand Down
4 changes: 2 additions & 2 deletions custom_components/family_safety/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"documentation": "https://github.com/pantherale0/ha-familysafety",
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/pantherale0/ha-familysafety/issues",
"requirements": ["pyfamilysafety==0.0.5"],
"requirements": ["pyfamilysafety==0.1.0"],
"ssdp": [],
"zeroconf": [],
"version": "1.0.0",
"version": "1.1.0b0",
"integration_type": "service"
}
11 changes: 11 additions & 0 deletions custom_components/family_safety/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,16 @@
"connection": "Unable to connect to the server.",
"unknown": "Unknown error occurred."
}
},
"options": {
"step": {
"init": {
"description": "Update Microsoft Family Safety configuration",
"data": {
"update_interval": "Update interval (seconds)",
"refresh_token": "Refresh token"
}
}
}
}
}

0 comments on commit d9fc0c6

Please sign in to comment.