Skip to content

Commit

Permalink
add switch arp_filter
Browse files Browse the repository at this point in the history
add switch with const.py
  • Loading branch information
dscao authored Jan 15, 2023
1 parent a066307 commit ae40fe3
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 27 deletions.
1 change: 1 addition & 0 deletions custom_components/ikuai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ async def get_access_token(self):
self._token_expire_time = time.time() + 60*60*2
return self._token
else:
_LOGGER.info("The password has been incorrect for many times, please reconfigure the ikuai integration.")
return

async def _async_update_data(self):
Expand Down
14 changes: 14 additions & 0 deletions custom_components/ikuai/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@
},
}


SWITCH_TYPES = {
"ikuai_arp_filter": {
"icon": "mdi:account-lock",
"label": "iKuai非绑定MAC不允许上网",
"name": "Arp_filter",
"turn_on_body": {"func_name":"arp","action":"seting","param":{"arp_filter":1}},
"turn_off_body": {"func_name":"arp","action":"seting","param":{"arp_filter":0}},
"show_body": {"func_name":"arp","action":"show","param":{"TYPE":"options"}},
"show_on": {'arp_filter': 1},
"show_off": {'arp_filter': 0},
},
}

DEVICE_TRACKERS = {
"myiphone": {
"label": "我的手机",
Expand Down
48 changes: 46 additions & 2 deletions custom_components/ikuai/data_fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
from .const import (
LOGIN_URL,
ACTION_URL,
DEVICE_TRACKERS,
DEVICE_TRACKERS,
SWITCH_TYPES,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -397,12 +398,47 @@ async def _get_ikuai_device_tracker(self, sess_key, macaddress):
self._datarefreshtimes[macaddress] = 0
_LOGGER.debug("%s refreshtimes: %s", macaddress, self._datarefreshtimes[macaddress])
elif self._datarefreshtimes.get(macaddress):
if self._datarefreshtimes[macaddress] < 2 :
if self._datarefreshtimes[macaddress] < 5 :
self._data["tracker"].append(self._datatracker[macaddress])
self._datarefreshtimes[macaddress] = self._datarefreshtimes[macaddress] + 1

return


async def _get_ikuai_switch(self, sess_key, name, show_body, show_on, show_off):
header = {
'Cookie': 'Cookie: username=admin; login=1; sess_key='+sess_key,
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Content-Type': 'application/json;charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.40 Safari/537.36',
}

json_body = show_body

url = self._host + ACTION_URL
_LOGGER.debug("Requests remaining: %s: %s", url, json_body)
try:
async with timeout(10):
resdata = await self._hass.async_add_executor_job(self.requestpost_json, url, header, json_body)
except (
ClientConnectorError
) as error:
raise UpdateFailed(error)
_LOGGER.debug(resdata)
if resdata == 401:
self._data = 401
return
if resdata["Result"] == 10014:
self._data = 401
return
if resdata.get("Data") == show_on:
self._data["switch"].append({"name":name,"onoff":"on"})
elif resdata.get("Data") == show_off:
self._data["switch"].append({"name":name,"onoff":"off"})
return


async def get_data(self, sess_key):
threads = [
Expand All @@ -423,6 +459,14 @@ async def get_data(self, sess_key):
]
await asyncio.wait(threads)

self._data["switch"] = []
threads = []
for switch in SWITCH_TYPES:
threads = [
self._get_ikuai_switch(sess_key, SWITCH_TYPES[switch]['name'], SWITCH_TYPES[switch]['show_body'], SWITCH_TYPES[switch]['show_on'], SWITCH_TYPES[switch]['show_off'])
]
await asyncio.wait(threads)

self._data["tracker"] = []
threads = []
for device_tracker in DEVICE_TRACKERS:
Expand Down
13 changes: 0 additions & 13 deletions custom_components/ikuai/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,6 @@ def __init__(self, hass, kind, coordinator):
self._attrs = {}
self._querytime = ""


async def get_access_token(self):
if time.time() < self._token_expire_time:
return self._token
else:
if self._allow_login == True:
self._token = await self._fetcher._login_ikuai()
if self._token == 10001:
self._allow_login = False
self._token_expire_time = time.time() + 60*60*2
return self._token
else:
return

@property
def name(self):
Expand Down
185 changes: 173 additions & 12 deletions custom_components/ikuai/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
CONF_PASS,
CONF_HOST,
ACTION_URL,
SWITCH_TYPES,
)


Expand All @@ -34,17 +35,183 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
pas = config_entry.data[CONF_PASS]

switchs = []
#_LOGGER.debug(coordinator.data.get("mac_control"))
switchsmac = []

if SWITCH_TYPES:
_LOGGER.debug("setup switchs")
for switch in SWITCH_TYPES:
switchs.append(IKUAISwitch(hass, switch, coordinator, host, username, passwd, pas))
_LOGGER.debug(SWITCH_TYPES[switch]["name"])
async_add_entities(switchs, False)

if coordinator.data.get("mac_control"):
listmacdata = coordinator.data.get("mac_control")
if isinstance(listmacdata, list):
_LOGGER.debug(listmacdata)
for mac in listmacdata:
#_LOGGER.debug(mac)
switchs.append(PVESwitch(hass, coordinator, host, username, passwd, pas, mac["id"]))
async_add_entities(switchs, False)
_LOGGER.debug(mac)
switchsmac.append(IKUAISwitchmac(hass, coordinator, host, username, passwd, pas, mac["id"]))
async_add_entities(switchsmac, False)



class IKUAISwitch(SwitchEntity):
_attr_has_entity_name = True
def __init__(self, hass, kind, coordinator, host, username, passwd, pas):
"""Initialize."""
super().__init__()
self.kind = kind
self.coordinator = coordinator
self._state = None
self._attr_device_info = {
"identifiers": {(DOMAIN, self.coordinator.host)},
"name": self.coordinator.data["device_name"],
"manufacturer": "iKuai",
"model": "iKuai Router",
"sw_version": self.coordinator.data["sw_version"],
}
self._attr_icon = SWITCH_TYPES[self.kind]['icon']
self._attr_device_class = "switch"
self._attr_entity_registry_enabled_default = True
self._hass = hass
self._token = ""
self._token_expire_time = 0
self._allow_login = True
self._fetcher = DataFetcher(hass, host, username, passwd, pas)
self._host = host
self._name = SWITCH_TYPES[self.kind]['name']
self._turn_on_body = SWITCH_TYPES[self.kind]['turn_on_body']
self._turn_off_body = SWITCH_TYPES[self.kind]['turn_off_body']
self._change = True
self._switchonoff = None

listswitch = self.coordinator.data.get("switch")

for switchdata in listswitch:
if switchdata["name"] == self._name:
self._switchonoff = switchdata["onoff"]

self._is_on = self._switchonoff == "on"
self._state = "on" if self._is_on == True else "off"


async def get_access_token(self):
if time.time() < self._token_expire_time:
return self._token
else:
if self._allow_login == True:
self._token = await self._fetcher._login_ikuai()
if self._token == 10001:
self._allow_login = False
self._token_expire_time = time.time() + 60*60*2
return self._token
else:
return

@property
def name(self):
"""Return the name."""
return f"{self._name}"

@property
def unique_id(self):
return f"{DOMAIN}_switch_{self.coordinator.host}_{self._name}"


@property
def should_poll(self):
"""Return the polling requirement of the entity."""
return False

@property
def is_on(self):
"""Check if switch is on."""
return self._is_on

async def async_turn_on(self, **kwargs):
"""Turn switch on."""
self._is_on = True
self._change = False
json_body = self._turn_on_body
await self._switch(json_body)
self._switchonoff = "on"

class PVESwitch(SwitchEntity):

async def async_turn_off(self, **kwargs):
"""Turn switch off."""
self._is_on = False
self._change = False
json_body = self._turn_off_body
await self._switch(json_body)
self._switchonoff = "off"

async def async_added_to_hass(self):
"""Connect to dispatcher listening for entity data notifications."""
self.async_on_remove(
self.coordinator.async_add_listener(self.async_write_ha_state)
)

async def async_update(self):
"""Update entity."""
await self.coordinator.async_request_refresh()

listswitch = self.coordinator.data.get("switch")

for switchdata in listswitch:
if switchdata["name"] == self._name:
self._switchonoff = switchdata["onoff"]

self._is_on = self._switchonoff == "on"
self._state = "on" if self._is_on == True else "off"
self._change = True


def requestpost_json(self, url, headerstr, json_body):
responsedata = requests.post(url, headers=headerstr, json = json_body, verify=False)
if responsedata.status_code != 200:
return responsedata.status_code
json_text = responsedata.content.decode('utf-8')
resdata = json.loads(json_text)
return resdata

async def _switch(self, action_body):
if self._allow_login == True:
sess_key = await self.get_access_token()
header = {
'Cookie': 'Cookie: username=admin; login=1; sess_key='+sess_key,
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Content-Type': 'application/json;charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.40 Safari/537.36',
}

json_body = action_body

url = self._host + ACTION_URL

try:
async with timeout(10):
resdata = await self._hass.async_add_executor_job(self.requestpost_json, url, header, json_body)
except (
ClientConnectorError
) as error:
raise UpdateFailed(error)
_LOGGER.debug("Requests remaining: %s", url)
_LOGGER.debug(resdata)
if resdata == 401:
self._data = 401
return
if resdata["Result"] == 10014:
self._data = 401
return

_LOGGER.info("操作ikuai: %s ", json_body)
return "OK"



class IKUAISwitchmac(SwitchEntity):
_attr_has_entity_name = True
def __init__(self, hass, coordinator, host, username, passwd, pas, mac):
"""Initialize."""
Expand Down Expand Up @@ -113,11 +280,6 @@ def should_poll(self):
"""Return the polling requirement of the entity."""
return True

# @property
# def state(self):
# """Return the state."""
# return self._state

@property
def extra_state_attributes(self):
"""Return device state attributes."""
Expand Down Expand Up @@ -211,5 +373,4 @@ async def _mac_control_switch(self, action_body):
return

_LOGGER.info("操作ikuai: %s ", json_body)
return "OK"

return "OK"

0 comments on commit ae40fe3

Please sign in to comment.