Skip to content

Commit 8b56550

Browse files
authored
Merge pull request #10 from rospogrigio/login_and_retrieve_tokenset
Login and retrieve tokenset
2 parents 68e35d0 + 9095951 commit 8b56550

File tree

9 files changed

+452
-71
lines changed

9 files changed

+452
-71
lines changed

README.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,27 @@ Alternatively, you can install daikin_residential through HACS by adding this re
99

1010
# Usage:
1111

12-
**NOTE: You must have your Daikin Cloud token set stored as a tokenset.json file in your /config folder (the same where configuration.yaml is). For instructions on how to retrieve this file, follow the guide at https://github.com/Apollon77/daikin-controller-cloud/blob/main/PROXY.md .**
12+
**NOTE: since v.2.0.x, the tokenset.json file is no longer needed because the integration can connect and retrieve the tokens autonomously. When installing v.2.0.x from a previous one, the integration must be deleted and re-added.**
1313

1414
The integration can be configured in two ways:
1515

1616
# 1. YAML config files
1717

18-
Just add the following line to your configuration.yaml file, and the Daikin devices connected to your cloud account will be created.
18+
Just add the following lines to your configuration.yaml file specifying the email and password used in the Daikin Residential App, and the Daikin devices connected to your cloud account will be created.
1919

2020
```
2121
daikin_residential:
22+
email: [your_email]
23+
password: [your_pwd]
24+
2225
```
2326

2427

2528
# 2. Using config flow
2629

2730
Start by going to Configuration - Integration and pressing the "+ ADD INTEGRATION" button to create a new Integration, then select Daikin Residential Controller in the drop-down menu.
2831

29-
Follow the instruction, you have actually nothing to configure, just make sure your tokenset.json fine is in the HA config folder. After pressing the "Submit" button, the integration will be added, and the Daikin devices connected to your cloud account will be created.
32+
Follow the instructions, you just have to type the email and password used in the Daikin Residential App. After pressing the "Submit" button, the integration will be added, and the Daikin devices connected to your cloud account will be created.
3033

3134

3235
# To-do list:
@@ -36,4 +39,4 @@ Follow the instruction, you have actually nothing to configure, just make sure y
3639

3740
# Thanks to:
3841

39-
This code is based on @Apollon77 's great work, in finding a way to retrieve the token set, and to send the HTTP commands over the cloud. This integration would not exist without his precious job.
42+
This code is based on @Apollon77 's great work, in finding a way to retrieve the token set, and to send the HTTP commands over the cloud. This integration would not exist without his precious job, my job was just to find a way to port his code from nodeJS to python, and then create the integration.

custom_components/daikin_residential/__init__.py

+34-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
import voluptuous as vol
66

77
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
8-
8+
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, SERVICE_RELOAD
99
from homeassistant.helpers.typing import HomeAssistantType
1010

11-
from .const import DOMAIN, DAIKIN_API, DAIKIN_DEVICES
11+
from .const import DOMAIN, DAIKIN_API, DAIKIN_DEVICES, CONF_TOKENSET
1212

1313
from .daikin_api import DaikinApi
1414

@@ -31,11 +31,39 @@
3131
COMPONENT_TYPES = ["climate", "sensor", "switch"]
3232

3333

34-
CONFIG_SCHEMA = vol.Schema(vol.All({DOMAIN: vol.Schema({})}), extra=vol.ALLOW_EXTRA)
34+
CONFIG_SCHEMA = vol.Schema(
35+
vol.All(
36+
{
37+
DOMAIN: vol.Schema(
38+
{vol.Required(CONF_EMAIL): str, vol.Required(CONF_PASSWORD): str}
39+
)
40+
}
41+
),
42+
extra=vol.ALLOW_EXTRA,
43+
)
3544

3645

3746
async def async_setup(hass, config):
38-
"""Establish connection with Daikin."""
47+
"""Setup the Daikin Residential component."""
48+
49+
async def _handle_reload(service):
50+
"""Handle reload service call."""
51+
_LOGGER.info("Reloading integration: retrieving new TokenSet.")
52+
try:
53+
daikin_api = hass.data[DOMAIN][DAIKIN_API]
54+
data = daikin_api._config_entry.data.copy()
55+
await daikin_api.retrieveAccessToken(data[CONF_EMAIL], data[CONF_PASSWORD])
56+
data[CONF_TOKENSET] = daikin_api.tokenSet
57+
hass.config_entries.async_update_entry(
58+
entry=daikin_api._config_entry, data=data
59+
)
60+
except Exception as e:
61+
_LOGGER.error("Failed to reload integration: %s", e)
62+
63+
hass.helpers.service.async_register_admin_service(
64+
DOMAIN, SERVICE_RELOAD, _handle_reload
65+
)
66+
3967
if DOMAIN not in config:
4068
return True
4169

@@ -46,13 +74,14 @@ async def async_setup(hass, config):
4674
DOMAIN, context={"source": SOURCE_IMPORT}, data=conf
4775
)
4876
)
77+
4978
return True
5079

5180

5281
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
5382
"""Establish connection with Daikin."""
5483

55-
daikin_api = DaikinApi(hass)
84+
daikin_api = DaikinApi(hass, entry)
5685
await daikin_api.getCloudDeviceDetails()
5786

5887
devices = await daikin_api.getCloudDevices()

custom_components/daikin_residential/config_flow.py

+31-14
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import voluptuous as vol
55

66
from homeassistant import config_entries
7+
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
78

89
from .daikin_api import DaikinApi
9-
from .const import DOMAIN
10+
from .const import DOMAIN, CONF_TOKENSET
1011

1112
_LOGGER = logging.getLogger(__name__)
1213

@@ -16,7 +17,7 @@ class FlowHandler(config_entries.ConfigFlow):
1617
"""Handle a config flow."""
1718

1819
VERSION = 1
19-
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL
20+
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
2021

2122
def __init__(self):
2223
"""Initialize the Daikin config flow."""
@@ -25,9 +26,11 @@ def __init__(self):
2526
@property
2627
def schema(self):
2728
"""Return current schema."""
28-
return vol.Schema({})
29+
return vol.Schema(
30+
{vol.Required(CONF_EMAIL): str, vol.Required(CONF_PASSWORD): str}
31+
)
2932

30-
async def _create_entry(self):
33+
async def _create_entry(self, email, password, tokenSet):
3134
"""Register new entry."""
3235
# if not self.unique_id:
3336
# await self.async_set_unique_id(password)
@@ -37,27 +40,41 @@ async def _create_entry(self):
3740

3841
await self.async_set_unique_id("DaikinResidentialController")
3942

40-
return self.async_create_entry(title="Daikin", data={})
43+
return self.async_create_entry(
44+
title="Daikin",
45+
data={CONF_EMAIL: email, CONF_PASSWORD: password, CONF_TOKENSET: tokenSet},
46+
)
4147

42-
async def _attempt_connection(self):
48+
async def _attempt_connection(self, email, password):
4349
"""Create device."""
4450
try:
45-
daikin_api = DaikinApi(self.hass)
46-
except Exception:
47-
return self.async_abort(reason="missing_config")
51+
daikin_api = DaikinApi(self.hass, None)
52+
except Exception as e:
53+
_LOGGER.error("Failed to initialize DaikinApi: %s", e)
54+
return self.async_abort(reason="init_failed")
55+
try:
56+
await daikin_api.retrieveAccessToken(email, password)
57+
except Exception as e:
58+
_LOGGER.error("Failed to retrieve Access Token: %s", e)
59+
return self.async_abort(reason="token_retrieval_failed")
4860
try:
4961
await daikin_api.getApiInfo()
50-
except Exception:
62+
except Exception as e:
63+
_LOGGER.error("Failed to connect to DaikinApi: %s", e)
5164
return self.async_abort(reason="cannot_connect")
5265

53-
return await self._create_entry()
66+
return await self._create_entry(email, password, daikin_api.tokenSet)
5467

5568
async def async_step_user(self, user_input=None):
5669
"""User initiated config flow."""
5770
if user_input is None:
5871
return self.async_show_form(step_id="user", data_schema=self.schema)
59-
return await self._attempt_connection()
72+
return await self._attempt_connection(
73+
user_input.get(CONF_EMAIL), user_input.get(CONF_PASSWORD)
74+
)
6075

6176
async def async_step_import(self, user_input):
62-
"""Import a config entry."""
63-
return await self._create_entry()
77+
"""Import a config entry from YAML."""
78+
return await self._attempt_connection(
79+
user_input.get(CONF_EMAIL), user_input.get(CONF_PASSWORD)
80+
)

custom_components/daikin_residential/const.py

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from homeassistant.const import (
44
CONF_DEVICE_CLASS,
5+
CONF_TOKEN,
56
CONF_ICON,
67
CONF_NAME,
78
CONF_TYPE,
@@ -13,6 +14,8 @@
1314

1415
DOMAIN = "daikin_residential"
1516

17+
CONF_TOKENSET = CONF_TOKEN + "set"
18+
1619
DAIKIN_DATA = "daikin_data"
1720
DAIKIN_API = "daikin_api"
1821
DAIKIN_DEVICES = "daikin_devices"

0 commit comments

Comments
 (0)