Skip to content

Commit

Permalink
refactor config flow
Browse files Browse the repository at this point in the history
organize imports / consts
authenticate during config flow
  • Loading branch information
sehaas committed Mar 28, 2021
1 parent 0e11904 commit 0e41bf7
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 115 deletions.
4 changes: 2 additions & 2 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import asyncio
import logging

from .const import DOMAIN

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant

from .const import DOMAIN

_LOGGER = logging.getLogger(__name__)

PLATFORMS = ["media_player"]
Expand Down
193 changes: 162 additions & 31 deletions config_flow.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,186 @@
import json
import logging

import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_NAME, CONF_MAC
from homeassistant.components import mqtt
from .const import DOMAIN, CONF_MQTT_IN, CONF_MQTT_OUT
from homeassistant.const import CONF_AUTHENTICATION, CONF_MAC, CONF_NAME, CONF_PIN

import voluptuous as vol
import logging
from .const import (
CONF_MQTT_IN,
CONF_MQTT_OUT,
DEFAULT_CLIENT_ID,
DEFAULT_MQTT_PREFIX,
DEFAULT_NAME,
DOMAIN,
)
from .helper import mqtt_pub_sub

_LOGGER = logging.getLogger(__name__)


class HisenseTvFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Example config flow."""
"""Hisense TV config flow."""

VERSION = 1
task_mqtt = None
task_auth = None

def __init__(self):
"""Initialize the config flow."""
self._mac = None
self._name = None
self._mqtt_in = None
self._mqtt_out = None
self._unsubscribe_auth = None
self._unsubscribe_sourcelist = None

async def _async_pin_needed(self, message):
_LOGGER.debug("_async_pin_needed")
self._unsubscribe()
self.task_auth = False
self.hass.async_create_task(
self.hass.config_entries.flow.async_configure(flow_id=self.flow_id)
)

async def _async_pin_not_needed(self, message):
_LOGGER.debug("_async_pin_not_needed")
self._unsubscribe()
self.task_auth = True
self.hass.async_create_task(
self.hass.config_entries.flow.async_configure(flow_id=self.flow_id)
)

async def _async_authcode_response(self, message):
self._unsubscribe()
payload = json.loads(message.payload)
_LOGGER.debug("_async_authcode_respone %s" % payload)
self.task_auth = payload.get("result") == 1
self.hass.async_create_task(
self.hass.config_entries.flow.async_configure(flow_id=self.flow_id)
)

def _unsubscribe(self):
if self._unsubscribe_auth is not None:
self._unsubscribe_auth()
self._unsubscribe_auth = None
if self._unsubscribe_sourcelist is not None:
self._unsubscribe_sourcelist()
self._unsubscribe_sourcelist = None

async def async_step_user(self, info):
if info is not None:
self._mac = info.get(CONF_MAC)
self._name = info.get(CONF_NAME)
self._mqtt_in = info.get(CONF_MQTT_IN)
self._mqtt_out = info.get(CONF_MQTT_OUT)
return self.async_create_entry(
title=self._name,
data={
CONF_MAC: self._mac,
CONF_NAME: self._name,
CONF_MQTT_IN: self._mqtt_in,
CONF_MQTT_OUT: self._mqtt_out,
},
if self.task_auth is True:
return self.async_show_progress_done(next_step_id="finish")

if self.task_auth is False:
self.task_auth = None
return self.async_show_progress_done(next_step_id="auth")

if info is None:
_LOGGER.debug("async_step_user INFO None")
return self.async_show_form(
step_id="user",
data_schema=vol.Schema(
{
vol.Required(CONF_NAME, default=DEFAULT_NAME): str,
vol.Required(CONF_MAC): str,
vol.Optional(CONF_MQTT_IN, default=DEFAULT_MQTT_PREFIX): str,
vol.Optional(CONF_MQTT_OUT, default=DEFAULT_MQTT_PREFIX): str,
}
),
)
else:
_LOGGER.debug("async_step_user NOT task_mqtt")
self.task_mqtt = {
CONF_MAC: info.get(CONF_MAC),
CONF_NAME: info.get(CONF_NAME),
CONF_MQTT_IN: info.get(CONF_MQTT_IN),
CONF_MQTT_OUT: info.get(CONF_MQTT_OUT),
}

default_mqtt_in = self._mqtt_in or "hisense"
default_mqtt_out = self._mqtt_out or "hisense"
return self.async_show_form(
step_id="user",
data_schema=vol.Schema(
{
vol.Required(CONF_MAC): str,
vol.Required(CONF_NAME, default=self._name): str,
vol.Optional(CONF_MQTT_IN, default=default_mqtt_in): str,
vol.Optional(CONF_MQTT_OUT, default=default_mqtt_out): str,
}
),
await self._check_authentication(client_id=DEFAULT_CLIENT_ID)

return self.async_show_progress(
step_id="user",
progress_action="progress_action",
)

async def _check_authentication(self, client_id):
self._unsubscribe_auth = await mqtt.async_subscribe(
hass=self.hass,
topic="%s/remoteapp/mobile/%s/ui_service/data/authentication"
% (self.task_mqtt.get(CONF_MQTT_IN), client_id),
msg_callback=self._async_pin_needed,
)
self._unsubscribe_sourcelist = await mqtt.async_subscribe(
hass=self.hass,
topic="%s/remoteapp/mobile/%s/ui_service/data/sourcelist"
% (self.task_mqtt.get(CONF_MQTT_IN), client_id),
msg_callback=self._async_pin_not_needed,
)
mqtt.publish(
hass=self.hass,
topic="%s/remoteapp/tv/ui_service/%s/actions/gettvstate"
% (self.task_mqtt.get(CONF_MQTT_OUT), client_id),
payload="",
)
mqtt.publish(
hass=self.hass,
topic="%s/remoteapp/tv/ui_service/%s/actions/sourcelist"
% (self.task_mqtt.get(CONF_MQTT_OUT), client_id),
payload="",
)

async def async_step_reauth(self, user_input=None):
self.task_auth = None
return await self.async_step_auth(user_input=user_input)

async def async_step_auth(self, user_input=None):
if self.task_auth is True:
_LOGGER.debug("async_step_auth finish")
return self.async_show_progress_done(next_step_id="finish")

if self.task_auth is False:
_LOGGER.debug("async_step_auth reauth")
return self.async_show_progress_done(next_step_id="reauth")

if user_input is None:
self.task_auth = None
_LOGGER.debug("async_step_auth show form")
return self.async_show_form(
step_id="auth",
data_schema=vol.Schema(
{
vol.Required(CONF_PIN): int,
}
),
)
else:
_LOGGER.debug("async_step_auth send authentication")
client_id = DEFAULT_CLIENT_ID
self._unsubscribe_auth = await mqtt.async_subscribe(
hass=self.hass,
topic="%s/remoteapp/mobile/%s/ui_service/data/authenticationcode"
% (self.task_mqtt.get(CONF_MQTT_IN), client_id),
msg_callback=self._async_authcode_response,
)
payload = json.dumps({"authNum": user_input.get(CONF_PIN)})
mqtt.publish(
hass=self.hass,
topic="%s/remoteapp/tv/ui_service/%s/actions/authenticationcode"
% (self.task_mqtt.get(CONF_MQTT_OUT), client_id),
payload=payload,
)
return self.async_show_progress(
step_id="auth",
progress_action="progress_action",
)

async def async_step_finish(self, user_input=None):
_LOGGER.debug("async_step_finish")
return self.async_create_entry(title=self._name, data=self.task_mqtt)

async def async_step_import(self, data):
"""Handle import from YAML."""
_LOGGER.warn("async_step_import")
_LOGGER.debug("async_step_import")
return self.async_create_entry(title=data[CONF_NAME], data=data)
14 changes: 6 additions & 8 deletions const.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
DEFAULT_NAME = "Hisense TV"
DOMAIN = "hisense_tv"
DATA_KEY = "media_player.hisense_tv"

ATTR_CODE = "auth_code"
CONF_MQTT_IN = "mqtt_in"
CONF_MQTT_OUT = "mqtt_out"

SERVICE_START_AUTHENTICATION = "start_authentication"
SERVICE_AUTHENTICATE = "authenticate_client"
ATTR_CODE = "auth_code"
DATA_KEY = "media_player.hisense_tv"
DEFAULT_CLIENT_ID = "HomeAssistant"
DEFAULT_MQTT_PREFIX = "hisense"
DEFAULT_NAME = "Hisense TV"
DOMAIN = "hisense_tv"
1 change: 1 addition & 0 deletions helper.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio

from homeassistant.components import mqtt


Expand Down
66 changes: 17 additions & 49 deletions media_player.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,45 @@
import asyncio
import json
import logging

import voluptuous as vol
import wakeonlan
import json

from homeassistant.components import mqtt
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.components.media_player import (
MediaPlayerEntity,
BrowseMedia,
PLATFORM_SCHEMA,
DEVICE_CLASS_TV,
PLATFORM_SCHEMA,
BrowseMedia,
MediaPlayerEntity,
)
from homeassistant.components.media_player.const import (
MEDIA_CLASS_APP,
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_CHANNEL,
MEDIA_CLASS_DIRECTORY,
MEDIA_TYPE_APP,
MEDIA_TYPE_APPS,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_TVSHOW,
SUPPORT_BROWSE_MEDIA,
SUPPORT_PLAY_MEDIA,
SUPPORT_SELECT_SOURCE,
SUPPORT_TURN_ON,
SUPPORT_TURN_OFF,
SUPPORT_TURN_ON,
SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_STEP,
SUPPORT_VOLUME_SET,
SUPPORT_BROWSE_MEDIA,
SUPPORT_PLAY_MEDIA,
)
from homeassistant.const import (
CONF_NAME,
CONF_MAC,
STATE_OFF,
STATE_ON,
SUPPORT_VOLUME_STEP,
)
from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import CONF_MAC, CONF_NAME, STATE_OFF, STATE_ON
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import entity_platform

from .const import (
ATTR_CODE,
CONF_MQTT_IN,
CONF_MQTT_OUT,
DOMAIN,
DEFAULT_CLIENT_ID,
DEFAULT_NAME,
SERVICE_AUTHENTICATE,
SERVICE_START_AUTHENTICATION,
ATTR_CODE,
DOMAIN,
)
from .helper import mqtt_pub_sub

Expand Down Expand Up @@ -105,14 +100,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
if uid is None:
uid = config_entry.entry_id

platform = entity_platform.current_platform.get()
platform.async_register_entity_service(
SERVICE_START_AUTHENTICATION, {}, "async_start_authentication"
)
platform.async_register_entity_service(
SERVICE_AUTHENTICATE, AUTHENTICATE_SCHEMA, "async_authenticate"
)

entity = HisenseTvEntity(
hass=hass, name=name, mqtt_in=mqtt_in, mqtt_out=mqtt_out, mac=mac, uid=uid
)
Expand All @@ -123,7 +110,7 @@ class HisenseTvEntity(MediaPlayerEntity):
def __init__(
self, hass, name: str, mqtt_in: str, mqtt_out: str, mac: str, uid: str
):
self._client = "HomeAssistant"
self._client = DEFAULT_CLIENT_ID
self._hass = hass
self._name = name
self._mqtt_in = mqtt_in or ""
Expand Down Expand Up @@ -664,22 +651,3 @@ async def async_play_media(self, media_type, media_id, **kwargs):
topic=self._out_topic("/remoteapp/tv/ui_service/%s/actions/launchapp"),
payload=payload,
)

async def async_start_authentication(self):
_LOGGER.debug("async_start_authentication")
mqtt.async_publish(
hass=self._hass,
topic=self._out_topic("/remoteapp/tv/ui_service/%s/actions/gettvstate"),
payload="",
)

async def async_authenticate(self, auth_code):
_LOGGER.debug("async_authenticate: %s" % auth_code)
payload = json.dumps({"authNum": auth_code})
mqtt.async_publish(
hass=self._hass,
topic=self._out_topic(
"/remoteapp/tv/ui_service/%s/actions/authenticationcode"
),
payload=payload,
)
16 changes: 0 additions & 16 deletions services.yaml

This file was deleted.

Loading

0 comments on commit 0e41bf7

Please sign in to comment.