136 lines
4.0 KiB
Python
136 lines
4.0 KiB
Python
"""Custom FPl api client"""
|
|
import sys
|
|
import json
|
|
import logging
|
|
|
|
import async_timeout
|
|
|
|
|
|
from .const import (
|
|
CONF_ACCOUNTS,
|
|
CONF_TERRITORY,
|
|
FPL_MAINREGION,
|
|
LOGIN_RESULT_FAILURE,
|
|
LOGIN_RESULT_OK,
|
|
TIMEOUT,
|
|
API_HOST,
|
|
)
|
|
|
|
from .FplMainRegionApiClient import FplMainRegionApiClient
|
|
from .FplNorthwestRegionApiClient import FplNorthwestRegionApiClient
|
|
|
|
|
|
_LOGGER = logging.getLogger(__package__)
|
|
|
|
|
|
URL_TERRITORY = API_HOST + "/cs/customer/v1/territoryid/public/territory"
|
|
|
|
|
|
class NoTerrytoryAvailableException(Exception):
|
|
"""Thrown when not possible to determine user territory"""
|
|
|
|
|
|
class FplApi:
|
|
"""A class for getting energy usage information from Florida Power & Light."""
|
|
|
|
def __init__(self, username, password, session, loop):
|
|
"""Initialize the data retrieval. Session should have BasicAuth flag set."""
|
|
self._username = username
|
|
self._password = password
|
|
self._session = session
|
|
self._loop = loop
|
|
self._territory = None
|
|
self.access_token = None
|
|
self.id_token = None
|
|
self.apiClient = None
|
|
|
|
async def getTerritory(self):
|
|
"""get territory"""
|
|
if self._territory is not None:
|
|
return self._territory
|
|
|
|
headers = {"userID": f"{self._username}", "channel": "WEB"}
|
|
async with async_timeout.timeout(TIMEOUT):
|
|
response = await self._session.get(URL_TERRITORY, headers=headers)
|
|
|
|
if response.status == 200:
|
|
json_data = json.loads(await response.text())
|
|
|
|
territoryArray = json_data["data"]["territory"]
|
|
if len(territoryArray) == 0:
|
|
raise NoTerrytoryAvailableException()
|
|
|
|
self._territory = territoryArray[0]
|
|
return territoryArray[0]
|
|
|
|
def isMainRegion(self):
|
|
"""Returns true if this account belongs to the main region, not northwest"""
|
|
return self._territory == FPL_MAINREGION
|
|
|
|
async def initialize(self):
|
|
"""initialize the api client"""
|
|
self._territory = await self.getTerritory()
|
|
|
|
# set the api client based on user's territory
|
|
if self.apiClient is None:
|
|
if self.isMainRegion():
|
|
self.apiClient = FplMainRegionApiClient(
|
|
self._username, self._password, self._loop, self._session
|
|
)
|
|
else:
|
|
self.apiClient = FplNorthwestRegionApiClient(
|
|
self._username, self._password, self._loop, self._session
|
|
)
|
|
|
|
async def get_basic_info(self):
|
|
"""returns basic info for sensor initialization"""
|
|
await self.initialize()
|
|
data = {}
|
|
data[CONF_TERRITORY] = self._territory
|
|
data[CONF_ACCOUNTS] = await self.apiClient.get_open_accounts()
|
|
|
|
return data
|
|
|
|
async def async_get_data(self) -> dict:
|
|
"""Get data from fpl api"""
|
|
await self.initialize()
|
|
data = {}
|
|
data[CONF_ACCOUNTS] = []
|
|
|
|
data[CONF_TERRITORY] = self._territory
|
|
|
|
login_result = await self.apiClient.login()
|
|
|
|
if login_result == LOGIN_RESULT_OK:
|
|
accounts = await self.apiClient.get_open_accounts()
|
|
|
|
data[CONF_ACCOUNTS] = accounts
|
|
for account in accounts:
|
|
data[account] = await self.apiClient.update(account)
|
|
|
|
await self.apiClient.logout()
|
|
return data
|
|
|
|
async def login(self):
|
|
"""method to use in config flow"""
|
|
try:
|
|
await self.initialize()
|
|
|
|
_LOGGER.info("Logging in")
|
|
# login and get account information
|
|
|
|
return await self.apiClient.login()
|
|
|
|
except Exception as exception:
|
|
_LOGGER.error("Error %s : %s", exception, sys.exc_info()[0])
|
|
return LOGIN_RESULT_FAILURE
|
|
|
|
async def async_get_open_accounts(self):
|
|
"""return open accounts"""
|
|
self.initialize()
|
|
return await self.apiClient.get_open_accounts()
|
|
|
|
async def logout(self):
|
|
"""log out from fpl"""
|
|
return await self.apiClient.logout()
|