Skip to content

Instantly share code, notes, and snippets.

@ellisdickinson46
Last active October 22, 2022 23:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ellisdickinson46/cbb4df0a6c169b6795b5dba119182f37 to your computer and use it in GitHub Desktop.
Save ellisdickinson46/cbb4df0a6c169b6795b5dba119182f37 to your computer and use it in GitHub Desktop.
A small python script to reboot a TP-Link PLC (tested on WPA4220)
#!/usr/bin/env python3
"""
reboot_plc.py:
This automation script automatically reboots a TP-Link Extender when
internet connectivity drops.
Tested using:
- TL-WPA4220 (v4.0, Firmware: 4.0.3)
"""
__author__ = "Ellis Dickinson"
__copyright__ = "Copyright 2022, ByteFloater"
__version__ = "0.2"
__status__ = "Development"
import time
import requests
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
def internet_connected() -> bool:
"""
Performs an internet connectivity check
Returns:
(bool): Boolean flag indicating the connectivity state
"""
url = "http://www.google.com"
timeout = 5
try:
# Internal -> External Connectivity
requests.get(url, timeout=timeout)
# External -> Internal Connectivity
requests.get(f"http://{get_current_ipv4()}", timeout=timeout)
return True
except (requests.ConnectionError, requests.Timeout):
return False
def get_current_ipv4() -> str:
"""
Returns the current external IPv4 address using a
service from SpDYN
Parameters:
None
Returns:
(str): IPv4 Address
"""
ip_address = requests.request("GET", "http://checkip4.spdyn.de/").text.strip()
return ip_address
def perform_restart(plc_addr: str) -> None:
"""
Attempts a restart of the TP-PLC
Parameters:
plc_addr (str): URL of target device
Returns:
None
"""
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(
service = Service(ChromeDriverManager().install()),
options = chrome_options
)
driver.implicitly_wait(10)
driver.delete_all_cookies()
driver.get(plc_addr)
login_box = driver.find_element(
By.ID,
"pcPassword"
)
login_box.clear()
login_box.send_keys('admin')
login_btn = driver.find_element(
By.ID,
"loginBtn"
)
login_btn.send_keys(Keys.ENTER)
reboot_btn = driver.find_element(
By.ID,
"top-control-reboot"
)
reboot_btn.click()
confirm_btn = driver.find_element(
By.CSS_SELECTOR,
"button.button-button.btn-msg.btn-msg-ok.btn-confirm"
)
confirm_btn.click()
time.sleep(100)
driver.quit()
if not internet_connected():
try:
perform_restart("http://[IP_ADDRESS]")
print("Restart attempt successful")
except NoSuchElementException:
print("Encountered a workflow error during the restart process.")
else:
print("Internet connected - no action required at this time.")
@3v1n0
Copy link

3v1n0 commented Oct 22, 2022

If you want you can also use the native api of the device.

See https://github.com/3v1n0/TL-WPA4220-python

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment