Initial commit of ge_kitchen scaffold

This commit is contained in:
Andrew Marks 2020-08-12 11:03:22 -04:00
parent 8b7de57434
commit cf856c5f86
7 changed files with 233 additions and 0 deletions

94
ge_kitchen/__init__.py Normal file
View File

@ -0,0 +1,94 @@
"""The ge_kitchen integration."""
import asyncio
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET
from homeassistant.core import HomeAssistant
from homeassistant.helpers import (
aiohttp_client,
config_entry_oauth2_flow,
config_validation as cv,
)
from . import api, config_flow
from .const import DOMAIN, OAUTH2_AUTHORIZE, OAUTH2_TOKEN
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_CLIENT_ID): cv.string,
vol.Required(CONF_CLIENT_SECRET): cv.string,
}
)
},
extra=vol.ALLOW_EXTRA,
)
# TODO List the platforms that you want to support.
# For your initial PR, limit it to 1 platform.
PLATFORMS = ["light"]
async def async_setup(hass: HomeAssistant, config: dict):
"""Set up the ge_kitchen component."""
hass.data[DOMAIN] = {}
if DOMAIN not in config:
return True
config_flow.OAuth2FlowHandler.async_register_implementation(
hass,
config_entry_oauth2_flow.LocalOAuth2Implementation(
hass,
DOMAIN,
config[DOMAIN][CONF_CLIENT_ID],
config[DOMAIN][CONF_CLIENT_SECRET],
OAUTH2_AUTHORIZE,
OAUTH2_TOKEN,
),
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Set up ge_kitchen from a config entry."""
implementation = await config_entry_oauth2_flow.async_get_config_entry_implementation(
hass, entry
)
session = config_entry_oauth2_flow.OAuth2Session(hass, entry, implementation)
# If using a requests-based API lib
hass.data[DOMAIN][entry.entry_id] = api.ConfigEntryAuth(hass, entry, session)
# If using an aiohttp-based API lib
hass.data[DOMAIN][entry.entry_id] = api.AsyncConfigEntryAuth(
aiohttp_client.async_get_clientsession(hass), session
)
for component in PLATFORMS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, component)
)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Unload a config entry."""
unload_ok = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(entry, component)
for component in PLATFORMS
]
)
)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok

58
ge_kitchen/api.py Normal file
View File

@ -0,0 +1,58 @@
"""API for ge_kitchen bound to Home Assistant OAuth."""
from asyncio import run_coroutine_threadsafe
from aiohttp import ClientSession
import my_pypi_package
from homeassistant import config_entries, core
from homeassistant.helpers import config_entry_oauth2_flow
# TODO the following two API examples are based on our suggested best practices
# for libraries using OAuth2 with requests or aiohttp. Delete the one you won't use.
# For more info see the docs at <insert url>.
class ConfigEntryAuth(my_pypi_package.AbstractAuth):
"""Provide ge_kitchen authentication tied to an OAuth2 based config entry."""
def __init__(
self,
hass: core.HomeAssistant,
config_entry: config_entries.ConfigEntry,
implementation: config_entry_oauth2_flow.AbstractOAuth2Implementation,
):
"""Initialize ge_kitchen Auth."""
self.hass = hass
self.config_entry = config_entry
self.session = config_entry_oauth2_flow.OAuth2Session(
hass, config_entry, implementation
)
super().__init__(self.session.token)
def refresh_tokens(self) -> dict:
"""Refresh and return new ge_kitchen tokens using Home Assistant OAuth2 session."""
run_coroutine_threadsafe(
self.session.async_ensure_token_valid(), self.hass.loop
).result()
return self.session.token
class AsyncConfigEntryAuth(my_pypi_package.AbstractAuth):
"""Provide ge_kitchen authentication tied to an OAuth2 based config entry."""
def __init__(
self,
websession: ClientSession,
oauth_session: config_entry_oauth2_flow.OAuth2Session,
):
"""Initialize ge_kitchen auth."""
super().__init__(websession)
self._oauth_session = oauth_session
async def async_get_access_token(self):
"""Return a valid access token."""
if not self._oauth_session.is_valid:
await self._oauth_session.async_ensure_token_valid()
return self._oauth_session.token

24
ge_kitchen/config_flow.py Normal file
View File

@ -0,0 +1,24 @@
"""Config flow for ge_kitchen."""
import logging
from homeassistant import config_entries
from homeassistant.helpers import config_entry_oauth2_flow
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
class OAuth2FlowHandler(
config_entry_oauth2_flow.AbstractOAuth2FlowHandler, domain=DOMAIN
):
"""Config flow to handle ge_kitchen OAuth2 authentication."""
DOMAIN = DOMAIN
# TODO Pick one from config_entries.CONN_CLASS_*
CONNECTION_CLASS = config_entries.CONN_CLASS_UNKNOWN
@property
def logger(self) -> logging.Logger:
"""Return logger."""
return logging.getLogger(__name__)

7
ge_kitchen/const.py Normal file
View File

@ -0,0 +1,7 @@
"""Constants for the ge_kitchen integration."""
DOMAIN = "ge_kitchen"
# TODO Update with your own urls
OAUTH2_AUTHORIZE = "https://www.example.com/auth/authorize"
OAUTH2_TOKEN = "https://www.example.com/auth/token"

16
ge_kitchen/manifest.json Normal file
View File

@ -0,0 +1,16 @@
{
"domain": "ge_kitchen",
"name": "ge_kitchen",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/ge_kitchen",
"requirements": [
"gekitchen==0.1.2"
],
"ssdp": [],
"zeroconf": [],
"homekit": {},
"dependencies": [],
"codeowners": [
"@ajmarks"
]
}

17
ge_kitchen/strings.json Normal file
View File

@ -0,0 +1,17 @@
{
"title": "ge_kitchen",
"config": {
"step": {
"pick_implementation": {
"title": "[%key:common::config_flow::title::oauth2_pick_implementation%]"
}
},
"abort": {
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]",
"authorize_url_timeout": "[%key:common::config_flow::abort::oauth2_authorize_url_timeout%]"
},
"create_entry": {
"default": "[%key:common::config_flow::create_entry::authenticated%]"
}
}
}

View File

@ -0,0 +1,17 @@
{
"config": {
"abort": {
"authorize_url_timeout": "[%key:common::config_flow::abort::oauth2_authorize_url_timeout%]",
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]"
},
"create_entry": {
"default": "[%key:common::config_flow::create_entry::authenticated%]"
},
"step": {
"pick_implementation": {
"title": "[%key:common::config_flow::title::oauth2_pick_implementation%]"
}
}
},
"title": "ge_kitchen"
}