Skip to content

Commit

Permalink
Merge pull request #73 from OTZro/master
Browse files Browse the repository at this point in the history
Add proxy support
  • Loading branch information
osk2 authored Jul 12, 2023
2 parents 0965f72 + b34406c commit a37ecfd
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 9 deletions.
6 changes: 4 additions & 2 deletions custom_components/panasonic_smart_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
DATA_COORDINATOR,
DEFAULT_UPDATE_INTERVAL,
DOMAIN,
CONF_PROXY,
CONF_UPDATE_INTERVAL,
DEFAULT_NAME,
PLATFORMS,
Expand All @@ -31,8 +32,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:

username = entry.data.get(CONF_USERNAME)
password = entry.data.get(CONF_PASSWORD)
proxy = entry.options.get(CONF_PROXY, '')
session = async_get_clientsession(hass)
client = SmartApp(session, username, password)
client = SmartApp(session, username, password, proxy)

_LOGGER.info(
"\n\
Expand All @@ -53,7 +55,7 @@ async def async_update_data():
_LOGGER,
name=DEFAULT_NAME,
update_method=async_update_data,
update_interval=timedelta(seconds=entry.data.get(CONF_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL)),
update_interval=timedelta(seconds=entry.options.get(CONF_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL)),
)

await coordinator.async_refresh()
Expand Down
47 changes: 43 additions & 4 deletions custom_components/panasonic_smart_app/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@
from typing import Any

import voluptuous as vol

from homeassistant import config_entries
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession

from .smartApp import SmartApp
from .smartApp.exceptions import PanasonicExceedRateLimit
from .const import (
DOMAIN,
CONF_PROXY,
CONF_UPDATE_INTERVAL,
DEFAULT_UPDATE_INTERVAL,
)
from .smartApp import SmartApp
from .smartApp.exceptions import PanasonicExceedRateLimit


class SmartAppFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
Expand All @@ -25,6 +28,12 @@ class SmartAppFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
def __init__(self) -> None:
self._errors: dict[str, str] = {}

@staticmethod
@callback
def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlowHandler:
"""Return the options flow."""
return OptionsFlowHandler(config_entry)

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
Expand All @@ -36,11 +45,13 @@ async def async_step_user(
if user_input is not None:
username = user_input[CONF_USERNAME]
password = user_input[CONF_PASSWORD]
proxy = user_input.get(CONF_PROXY, '')
session = async_get_clientsession(self.hass)
client = SmartApp(
session=session,
account=username,
password=password,
proxy=proxy,
)

try:
Expand All @@ -63,6 +74,7 @@ async def _show_config_form(
{
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Optional(CONF_PROXY, default=None): str,
vol.Optional(CONF_UPDATE_INTERVAL, default=DEFAULT_UPDATE_INTERVAL): int,
}
),
Expand All @@ -72,3 +84,30 @@ async def _show_config_form(
async def _test_credentials(self, client) -> True:
await client.login()
return True

class OptionsFlowHandler(config_entries.OptionsFlow):
def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
"""Initialize options flow."""
self.config_entry = config_entry

async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Manage the options."""
if user_input is not None:
username = self.config_entry.data.get(CONF_USERNAME)
return self.async_create_entry(title=username, data=user_input)

return self.async_show_form(
step_id="init",
data_schema=vol.Schema(
{
vol.Optional(CONF_PROXY, default=self.config_entry.options.get(
CONF_PROXY, ''
)): str,
vol.Optional(CONF_UPDATE_INTERVAL, default=self.config_entry.options.get(
CONF_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL
)): int,
}
),
)
1 change: 1 addition & 0 deletions custom_components/panasonic_smart_app/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
DATA_CLIENT = "client"
DATA_COORDINATOR = "coordinator"

CONF_PROXY = "proxy"
CONF_UPDATE_INTERVAL = "update_interval"

DEVICE_CLASS_SWITCH = "switch"
Expand Down
10 changes: 7 additions & 3 deletions custom_components/panasonic_smart_app/smartApp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
EXCEPTION_DEVICE_OFFLINE,
EXCEPTION_DEVICE_NOT_RESPONDING,
EXCEPTION_INVALID_REFRESH_TOKEN,
EXCEPTION_DEVICE_JP_INFO,
)
from .utils import chunks
from . import urls
Expand Down Expand Up @@ -64,9 +65,10 @@ async def wrapper_call(*args, **kwargs):


class SmartApp(object):
def __init__(self, session, account, password):
def __init__(self, session, account, password, proxy=None):
self.account = account
self.password = password
self._proxy = proxy
self._session = session
self._devices = []
self._commands = []
Expand Down Expand Up @@ -238,7 +240,7 @@ async def request(
resp = None
headers["user-agent"] = USER_AGENT
_LOGGER.debug(
f"Making request to {endpoint} with headers {headers} and data {data}"
f"Making request to {endpoint} with headers {headers} and data {data}, proxy: {self._proxy}"
)
try:
response = await self._session.request(
Expand All @@ -248,6 +250,7 @@ async def request(
params=params,
headers=headers,
timeout=REQUEST_TIMEOUT,
proxy=self._proxy,
)
except:
auth = headers.get("auth", None)
Expand Down Expand Up @@ -276,7 +279,8 @@ async def request(

offline_exceptions = [
EXCEPTION_DEVICE_OFFLINE,
EXCEPTION_DEVICE_NOT_RESPONDING
EXCEPTION_DEVICE_NOT_RESPONDING,
EXCEPTION_DEVICE_JP_INFO,
]
if resp.get("StateMsg") in offline_exceptions:
auth = headers.get("auth", None)
Expand Down
1 change: 1 addition & 0 deletions custom_components/panasonic_smart_app/smartApp/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
EXCEPTION_COMMAND_NOT_FOUND = "無法透過CommandId取得Commmand"
EXCEPTION_DEVICE_OFFLINE = "deviceOffline"
EXCEPTION_DEVICE_NOT_RESPONDING = "deviceNoResponse"
EXCEPTION_DEVICE_JP_INFO = "503:DeviceJPInfo:aStatusCode"
EXCEPTION_TOKEN_EXPIRED = "無法依據您的CPToken,auth取得相關資料"
EXCEPTION_INVALID_REFRESH_TOKEN = "無效RefreshToken"
EXCEPTION_CPTOKEN_EXPIRED = "此CPToken已經逾時"
Expand Down
11 changes: 11 additions & 0 deletions custom_components/panasonic_smart_app/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"data": {
"username": "Panasonic Smart App username",
"password": "Panasonic Smart App password",
"proxy": "Proxy URL (optional)",
"update_interval": "Update interval (second)"
}
}
Expand All @@ -18,5 +19,15 @@
"abort": {
"single_instance_allowed": "Only a single instance is allowed."
}
},
"options": {
"step": {
"init": {
"data": {
"proxy": "Proxy URL (optional)",
"update_interval": "Update interval (second)"
}
}
}
}
}
11 changes: 11 additions & 0 deletions custom_components/panasonic_smart_app/translations/zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"data": {
"username": "Panasonic Smart App 帳號",
"password": "Panasonic Smart App 密碼",
"proxy": "代理伺服器(選填)",
"update_interval": "更新時間間隔(秒)"
}
}
Expand All @@ -18,5 +19,15 @@
"abort": {
"single_instance_allowed": "重複設定。僅能建立一個實例"
}
},
"options": {
"step": {
"init": {
"data": {
"proxy": "代理伺服器(選填)",
"update_interval": "更新時間間隔(秒)"
}
}
}
}
}

0 comments on commit a37ecfd

Please sign in to comment.