Удаленная перезагрузка роутера TP-Link

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Здравствуйте, пытаюсь удаленно(по wifi сети роутера) перезагрузить роутер TP-link TL-MR3220 с модуля ESP32. Застрял на подтверждении перезагрузки. Авторизируюсь, получаю страницу со скриптами перезагрузки и не понимаю как подтвердить перезагрузку. По идее как то нужно отправить onSubmit="return true". Но куда и что отправить не понимаю. wget.exe на ПК делает полноценную перезагрузку командой:

wget.exe --http-user=admin --http-password=admin --referer=http://192.168.0.1:1987/userRpm/SysRebootRpm.htm http://192.168.0.1:1987/userRpm/SysRebootRpm.htm?Reboot=1

Вот собственно скеч который загружает страницу перезагрузки:

#include <WiFi.h>
#include <HTTPClient.h>
void setup() {
  Serial.begin(115200);
  WiFi.begin("ssid", "pass");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500); Serial.print(".");
  }
    HTTPClient http;
    http.begin("http://192.168.0.1:1987/userRpm/SysRebootRpm.htm");
    http.setAuthorization("admin", "admin");
    http.addHeader("Referer", "http://192.168.0.1:1987/userRpm/SysRebootRpm.htm");
    http.addHeader("Reboot", "1");
//    http.addHeader("onSubmit", "return 1"); // Не работает. Наверное не тут его нужно писать
    Serial.printf("[HTTP] GET...code: %d\n", http.GET());
    Serial.println(http.getString());
    http.end();
}
  void loop() {}

В ответ получаю:

<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<HTML>
<HEAD><TITLE>TL-MR3220</TITLE>
<META http-equiv=Pragma content=no-cache>
<META http-equiv=Expires content="wed, 26 Feb 1997 08:21:57 GMT">
<LINK href="/dynaform/css_main.css" rel=stylesheet type="text/css">
<SCRIPT language="javascript" src="/dynaform/common.js" type="text/javascript"></SCRIPT>
<SCRIPT language="javascript" type="text/javascript"><!--
if(window.parent == window){window.location.href="http://192.168.0.1";}
function Click(){ return false;}
document.oncontextmenu=Click;
//--></SCRIPT>

<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<SCRIPT type="text/javascript"><!--//
function doSubmit()
{
	if(confirm(js_to_reboot="Are you sure to reboot the Device?"))
	{
		location.href = "/userRpm/SysRebootRpm.htm";
		return true;
	}
	else 
	{
		return false;
	}
}
//--></SCRIPT>
</HEAD>
<BODY onLoad="setTagStr(document,'ntw_sys_reboot');LoadHelp('SysRebootHelpRpm.htm'); resize(this);" onResize="resize(this);">
<CENTER>
  <FORM action="SysRebootRpm.htm" enctype="multipart/form-data" method="get" onSubmit="return doSubmit();">
    <TABLE id="autoWidth">
      <TBODY>
        <TR>
          <TD class=h1 id="t_title">Reboot</TD>
        </TR>
        <TR>
          <TD class=blue></TD>
        </TR>
        <TR>
          <TD class=info id = "t_notice">Click this button to reboot the device.</TD>
        </TR>
        <TR>
          <TD class="mbtn"><INPUT name="Reboot" type="submit" class="buttonBig" value="Reboot" id = "reboot"></TD>
        </TR>
        <TR>
          <TD class=blue></TD>
        </TR>
      </TBODY>
    </TABLE>
  </FORM>
</CENTER>
</BODY>
<HEAD>
<META http-equiv="pragma" content="no-cache">
</HEAD>
</HTML>

В браузере место до которого дошел выглядит так:

также нашел на гитхабе файловую систему роутера 820го с таким же скриптом https://github.com/iAbadia/TL-WR802NV3/blob/master/src/webs/web_pages/en...

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Проблема решена.

Скеч перезагружает роутеры TP-Link:

#include <WiFi.h>
#include <HTTPClient.h>
const char* IP_port = "http:// 192. 168. 0.1:80"; // Убрать пробелы, заменить на свой адрес
#define RouterLogin "admin"
#define RouterPassword "admin"
void setup() {
  Serial.begin(115200);
  WiFi.begin("ssid", "pass");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500); Serial.print(".");
  }
    HTTPClient http;
    http.begin(String(IP_port) + "/userRpm/SysRebootRpm.htm?Reboot=1");
    http.setAuthorization(RouterLogin, RouterPassword);
    http.addHeader("User-Agent","ESP32 wrower");
    http.addHeader("Referer", String(IP_port) + "/userRpm/SysRebootRpm.htm");
    Serial.printf("[HTTP] GET...code: %d\n", http.GET());
//    Serial.println(http.getString()); // Выдаст вебстраничку ответа 
    http.end();
}
  void loop() {}

Тут описание скриптов под win, linux, android https://webkabi.net/skript-udalyonnoj-perezagruzki-wi-fi-routera-tp-link-tl-wr1042nd

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Подпишусь! У меня правда TP-LINK с OpenWrt но проблема аналогичная )))

Вижу несколько проблем:

1. Если отваливается ESP решаем через скрипт, скрипту добавить разрешения на исполнение и дописать в CRON задание:
* * * * * /usr/espcheck.sh
 

#!/bin/sh
# Rebooting router if internet connection disappeared %limit% seconds ago

limit=300
checkcount=2

# адрес на котором висит ESP
checkaddress='192.168.1.224'

d='/tmp/disconnected'

if ! ping -c "$checkcount" "$checkaddress"; then
	if [ -f "$d" ]; then
		dtime=`cat "$d"`
		diff=$(( `date +%s` - $dtime ))
		if [ "$diff" -gt "$limit" ]; then
			echo "Last internet connection: $(date -d @"$dtime" "+%F %T"), $diff second ago, rebooting..."
			reboot
		fi
	else
		echo "ESP connection failed, saving timestamp"
		date +%s > "$d"
	fi
else
	if [ -f "$d" ]; then
		rm $d
	fi
fi

2. Если отваливается INET решаем аналогично, для проверки используем доступность адреса 8.8.8.8

3. А вот если ESP подключается, сбрасывает данные на адрес сервера в интернете и отключается надо подумать )))
 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

вариант использовать роутер который не надо перезагружать годами не предлагать?
опять же поставить реле нормально замкнутое на питание или на кнопку сброса роутера + МК гораздо проще и надежнее.

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Не понял вашей проблемы. Из OpenWRT все пинговать можно и перезагружаться без ответов. А когда ESP видит интернет, вообще все ок. Время пинга разве что если большое можно перезагружаться.

Тестовый скеч дописал. Пингует гугл каждые 30 секунд, при отсутствии пинга настойчиво просит роутер перезагрузится пока не достучится до него и тот не ответит либо пока wifi не отвалится. Ждет 3 минуты соединения с инетом и по кругу. Светодиод мигает, показывая количество перезагрузок с момента включения ESP. Нужно тестить. Кстати, когда роутер раскрутить можно то и ESP можно внутрь запихнуть и вообще припаяться к RST роутера или транзистором питание дергать.  Не мой случай.

#include <WiFi.h>
#include <ESP32Ping.h> //github.com/marian-craciunescu/ESP32Ping
#include <HTTPClient.h>
const char* IP_port = "http:// 192.168.0.1:80";// Удалить пробел
#define RouterLogin "admin"
#define RouterPassword "admin"
uint32_t TIME_TO_SLEEP = 30e6;// Время между пингами 30 секунд
#define waitAfterReboot 180 // Время бездействия после перезагрузки в ожидании сети
#define LED_BUILTIN 2
RTC_DATA_ATTR uint32_t resetCount=3;// Количество перезагрузок роутера. Мигаем светодиодом столько же раз/2
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  WiFi.begin("ssid", "pass");
  while (WiFi.status() != WL_CONNECTED) {
    delay(50); Serial.print(".");
    if (millis()>60e3) ESP.restart();// Если не можем подключится к wifi - перезагружаемся
  }
  if (!Ping.ping("google.com.ua", 3)) {
    HTTPClient http;
    int HTTPcode = 0;
    do {
      http.begin(String(IP_port) + "/userRpm/SysRebootRpm.htm?Reboot=1");
      http.setAuthorization(RouterLogin, RouterPassword);
      http.addHeader("User-Agent", "ESP-WROOM32 Arduino");
      http.addHeader("Referer", String(IP_port) + "/userRpm/SysRebootRpm.htm");
      HTTPcode = http.GET();
      Serial.printf("[HTTP] GET...code: %d\n", HTTPcode);
      //    Serial.println(http.getString()); // Выдаст вебстраничку jndtnf
      http.end();
    } while ((HTTPcode != 200) && WL_CONNECTED&&(millis()<120e3));// Перезагружаем роутер пока он не ответит положительно или связь не отвалится или 2 минуты попыток не закончатся
    Serial.println("Rebooting Router Ok");
    ++resetCount;
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED on (HIGH is the voltage level)
    delay(waitAfterReboot);
    //TIME_TO_SLEEP = waitAfterReboot*1e6
  } else {
    Serial.println("Ping Ok");
  }
  for (uint32_t i = resetCount; i > 0; i--) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));   // turn the LED on (HIGH is the voltage level)
    delay(50);
  }
  Serial.println("resetCount=" + String(resetCount));

  if (micros()<TIME_TO_SLEEP-100){
    TIME_TO_SLEEP -= micros();
  } else {
    ESP.restart();
    }
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP);
  esp_deep_sleep_start();
}
void loop() {}

 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andycat пишет:

вариант использовать роутер который не надо перезагружать годами не предлагать?
опять же поставить реле нормально замкнутое на питание или на кнопку сброса роутера + МК гораздо проще и надежнее.

он такой и есть )))
к сожалению приходится использовать пакет прикладного ПО разработанный в 1990х годах, там есть ошибки, без этого пакета роутер (TL-WR842ND) отработал без перезагрузки 7 лет )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

p-a-h-a! Осталось адаптировать твой скетч для перезагрузки самой ESP, если пинг не проходит и проблема в самой ESP...

Сделал так:
 

void loop()
{
  server.handleClient();
  if (tm == 0) {                       // если таймер отработал
    flipper.detach();                 // выключаем
    tm = interval;
    // сбрасываем переменную таймера
    int j = 0;
    int k = 0;
    for (int i = 0; i < 3; i++) {
      ret = Ping.ping(WiFi.gatewayIP());
      if (ret) j++;
      reti = Ping.ping(host);
      if (reti) k++;
    }
    if (!j && !k)ESP.restart();
    flipper.attach(1, flip);          // включаем прерывание по таймеру
  }
}

Отрабатывает:
 

load 0x4010f000, len 3584, room 16 
tail 0
chksum 0xb0
csum 0xb0
v2843a5ac
~ld
.....
WiFi connected
IP address: 192.168.1.22
SSID: OpenWrt
RSSI: -51
MAC address: 

Connecting to 
OpenWrt

WiFi connected..!
Got IP: 192.168.1.22
HTTP server started
Humidity: 47.30%  Temperature: 26.10°C 
Humidity: 47.30%  Temperature: 26.10°C 
Humidity: 48.60%  Temperature: 26.00°C 

sadman41
Offline
Зарегистрирован: 19.10.2016

Софт из 90-х на ТПлинке? Сеть Иола на нем поднята что-ли?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:
Софт из 90-х на ТПлинке? Сеть Иола на нем поднята что-ли?

датчик температуры на 3 шт. DS18B20  на  USB-UARTe )))

малёхо приврал...2003 года оная поделка

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

ua6em, рад что пригодилось. На ESP только метеостанция крутится? Есть ссылка посмотреть на исходники? Как я понимаю есп поднимает сервер и по запросу выдает данные о погоде дома? Недавно делал несколько устройств (метеостанцию в том числе) на батарейном питании. Немного по другому все было - ESP это клиент а сервер от него раз в несколько минут принимает данные и хранит. Сервер narodmon.ru и для других устройств(влажность почвы цветов, сигнализация...  - телеграм. Все остальное врем ESP спит чтоб батарейки не сели да и лишний раз не подогревает датчики. Так метеостанция с небольшой солнечной батареей в постоянной тени уже 4 месяца работает и садится не собирается а датчик открытия двери 1000 сообщений в телеграм кинул на двух батарейках ААА. Время активности от 0,25 секунд выходит. Кстати, библиотека ESP32Ping на 8266 завелась без проблем?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

p-a-h-a я просто изучаю возможности ESP и 8266 и 32, библиотеки соответствующие, работают, код из интернета беру, правлю ошибки, до реального полностью завершенного устройства еще не дошёл