Skip to content

Commit 63cd90c

Browse files
committed
Added missing daikin_api.py
1 parent 36e9355 commit 63cd90c

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
"""Platform for the Daikin AC."""
2+
import datetime
3+
import functools
4+
import json
5+
import logging
6+
import requests
7+
8+
from homeassistant.util import Throttle
9+
10+
from .const import DOMAIN, DAIKIN_DEVICES
11+
12+
from .daikin_base import Appliance
13+
14+
_LOGGER = logging.getLogger(__name__)
15+
16+
TOKENSET_FILE = "tokenset.json"
17+
18+
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(seconds=15)
19+
20+
21+
class DaikinApi:
22+
"""Daikin Residential API."""
23+
24+
def __init__(self, hass):
25+
"""Initialize a new Daikin Residential API."""
26+
# super()
27+
self.hass = hass
28+
self.tokenSet = None
29+
tokenFile = self.hass.config.path(TOKENSET_FILE)
30+
_LOGGER.info("Initialing Daikin Residential API (%s)...", tokenFile)
31+
try:
32+
with open(tokenFile) as jsonFile:
33+
jsonObject = json.load(jsonFile)
34+
self.tokenSet = jsonObject
35+
jsonFile.close()
36+
except IOError:
37+
_LOGGER.error("tokenset.json file not found in config folder.")
38+
raise Exception("tokenset.json file not found in config folder.")
39+
40+
_LOGGER.info("Initialized Daikin Residential API")
41+
_LOGGER.debug(
42+
"Daikin Residential API token is [%s]", self.tokenSet["access_token"]
43+
)
44+
45+
async def doBearerRequest(self, resourceUrl, options=None, refreshed=False):
46+
if self.tokenSet is None:
47+
raise Exception(
48+
"Please provide a TokenSet or use the Proxy server to Authenticate once"
49+
)
50+
51+
if not resourceUrl.startswith("http"):
52+
resourceUrl = "https://api.prod.unicloud.edc.dknadmin.be" + resourceUrl
53+
54+
headers = {
55+
"user-agent": "Daikin/1.6.1.4681 CFNetwork/1209 Darwin/20.2.0",
56+
"x-api-key": "xw6gvOtBHq5b1pyceadRp6rujSNSZdjx2AqT03iC",
57+
"Authorization": "Bearer " + self.tokenSet["access_token"],
58+
"Content-Type": "application/json",
59+
}
60+
61+
_LOGGER.debug("BEARER REQUEST URL: %s", resourceUrl)
62+
_LOGGER.debug("BEARER REQUEST HEADERS: %s", headers)
63+
if options is not None and "method" in options and options["method"] == "PATCH":
64+
_LOGGER.debug("BEARER REQUEST JSON: %s", options["json"])
65+
func = functools.partial(
66+
requests.patch, resourceUrl, headers=headers, data=options["json"]
67+
)
68+
# res = requests.patch(resourceUrl, headers=headers, data=options["json"])
69+
else:
70+
func = functools.partial(requests.get, resourceUrl, headers=headers)
71+
# res = requests.get(resourceUrl, headers=headers)
72+
try:
73+
res = await self.hass.async_add_executor_job(func)
74+
except Exception as e:
75+
_LOGGER.error("REQUEST FAILED: %s", e)
76+
_LOGGER.debug("BEARER RESPONSE CODE: %s", res.status_code)
77+
78+
if res.status_code == 200:
79+
try:
80+
return res.json()
81+
except Exception:
82+
return res.text
83+
if res.status_code == 204:
84+
return True
85+
86+
if not refreshed and res.status_code == 401:
87+
_LOGGER.info("TOKEN EXPIRED: will refresh it (%s)", res.status_code)
88+
await self.refreshAccessToken()
89+
return await self.doBearerRequest(resourceUrl, options, True)
90+
91+
raise Exception("Communication failed! Status: " + str(res.status_code))
92+
93+
async def refreshAccessToken(self):
94+
"""Attempt to refresh the Access Token."""
95+
url = "https://cognito-idp.eu-west-1.amazonaws.com"
96+
97+
headers = {
98+
"Content-Type": "application/x-amz-json-1.1",
99+
"x-amz-target": "AWSCognitoIdentityProviderService.InitiateAuth",
100+
"x-amz-user-agent": "aws-amplify/0.1.x react-native",
101+
"User-Agent": "Daikin/1.6.1.4681 CFNetwork/1220.1 Darwin/20.3.0",
102+
}
103+
ref_json = {
104+
"ClientId": "7rk39602f0ds8lk0h076vvijnb",
105+
"AuthFlow": "REFRESH_TOKEN_AUTH",
106+
"AuthParameters": {"REFRESH_TOKEN": self.tokenSet["refresh_token"]},
107+
}
108+
try:
109+
func = functools.partial(requests.post, url, headers=headers, json=ref_json)
110+
res = await self.hass.async_add_executor_job(func)
111+
# res = requests.post(url, headers=headers, json=ref_json)
112+
except Exception as e:
113+
_LOGGER.error("REQUEST FAILED: %s", e)
114+
_LOGGER.info("REFRESHACCESSTOKEN RESPONSE CODE: %s", res.status_code)
115+
_LOGGER.debug("REFRESHACCESSTOKEN RESPONSE: %s", res.json())
116+
res_json = res.json()
117+
118+
if (
119+
res_json["AuthenticationResult"] is not None
120+
and res_json["AuthenticationResult"]["AccessToken"] is not None
121+
and res_json["AuthenticationResult"]["TokenType"] == "Bearer"
122+
):
123+
self.tokenSet["access_token"] = res_json["AuthenticationResult"][
124+
"AccessToken"
125+
]
126+
self.tokenSet["id_token"] = res_json["AuthenticationResult"]["IdToken"]
127+
self.tokenSet["expires_at"] = int(
128+
datetime.datetime.now().timestamp()
129+
) + int(res_json["AuthenticationResult"]["ExpiresIn"])
130+
_LOGGER.debug("NEW TOKENSET: %s", self.tokenSet)
131+
tokenFile = self.hass.config.path(TOKENSET_FILE)
132+
with open(tokenFile, "w") as outfile:
133+
json.dump(self.tokenSet, outfile)
134+
135+
# self.emit('token_update', self.tokenSet);
136+
return self.tokenSet
137+
raise Exception(
138+
"Token refresh was not successful! Status: " + str(res.status_code)
139+
)
140+
141+
async def getApiInfo(self):
142+
"""Get Daikin API Info."""
143+
return await self.doBearerRequest("/v1/info")
144+
145+
async def getCloudDeviceDetails(self):
146+
"""Get pure Device Data from the Daikin cloud devices."""
147+
return await self.doBearerRequest("/v1/gateway-devices")
148+
149+
async def getCloudDevices(self):
150+
"""Get array of DaikinResidentialDevice objects and get their data."""
151+
devices = await self.getCloudDeviceDetails()
152+
res = {}
153+
for dev in devices or []:
154+
res[dev["id"]] = Appliance(dev, self)
155+
return res
156+
157+
@Throttle(MIN_TIME_BETWEEN_UPDATES)
158+
async def async_update(self, **kwargs):
159+
"""Pull the latest data from Daikin."""
160+
_LOGGER.debug("API UPDATE")
161+
162+
json_data = await self.getCloudDeviceDetails()
163+
for dev_data in json_data or []:
164+
self.hass.data[DOMAIN][DAIKIN_DEVICES][dev_data["id"]].setJsonData(dev_data)

0 commit comments

Comments
 (0)