Функция stationDisconnectedHandler не работает

Brand2
Offline
Зарегистрирован: 25.04.2018

Хочу открывать дверь с помощью реле,которое включается при наличии в зоне доступа WiFi смартфона.

Все работает отлично когда я включаю и выключаю WiFi смартфона в настройках ,реле включается и отключается .Когда вхожу в зону точки доступа реле тоже включается нормально.

Проблемма начинается ,когда я покидаю зону точки доступа,вижу что на телефоне уже отключился WiFi ,но реле остается включенным,т.е модуль выдает Сonnected,

Когда же я вновь приближаюсь к зоне приема WiFi,получаю Disconnected на секунду примерно и тут же

опять Connected.

Такое впечатление что функция onStationDisconnected не работает при постепенном уменьшении сигнала подключенного вайфая.

Может кто знает почему так происходит?

#include <ESP8266WiFi.h>

const char *ssid = "DELTA_unlocker";
const char *password = "12345678";

unsigned long previousMillis = 0;
const long interval = 7000;
const int SleepTime = 7;

bool ConnectFlag = false;

WiFiEventHandler stationConnectedHandler; // событие - соединение
WiFiEventHandler stationDisconnectedHandler; // событие - разъединение

void setup() {
  Serial.begin(115200);
  pinMode(13, OUTPUT); // реле на GPIO13 (D7)
  digitalWrite(13, HIGH); // начальное значение
  WiFi.persistent(false); // бережем флеш-память, не перезаписываем данные подключения, если они не изменились с прошлой загрузки
  WiFi.mode(WIFI_AP); // Режим точки доступа
  WiFi.softAP(ssid, password);

  stationConnectedHandler = WiFi.onSoftAPModeStationConnected(&onStationConnected); // при соединении переходим к функции
  stationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(&onStationDisconnected); // при разъединении переходим к функции

}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval && ConnectFlag == false) {
    previousMillis = currentMillis;
    Serial.println("Sleep "+String(SleepTime)+" Sec.");
  //  ESP.deepSleep(SleepTime * 1000000, WAKE_RFCAL);
  } 
}

void onStationConnected(const WiFiEventSoftAPModeStationConnected& evt) { // при коннекте - включаем реле
  Serial.print("CONNECTED: ");
  digitalWrite(13, LOW);
  ConnectFlag = true;
  Serial.println(macToString(evt.mac)); // МАС-адрес в порт
}

void onStationDisconnected(const WiFiEventSoftAPModeStationDisconnected& evt) { // при дисконнекте - выключаем реле
  Serial.print("DISCONNECTED: ");
  digitalWrite(13, HIGH);
  ConnectFlag = false;
  Serial.println(macToString(evt.mac)); // МАС-адрес в порт
}

String macToString(const unsigned char* mac) { // Получаем МАС-адрес клиента в виде строки (может пригодиться при идентификации)
  char buf[20];
  snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  return String(buf);
}

 

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

Да, потому что так это не работает.

Ваш телефон в отличии от вашего модуля постоянно сканирует окружение. Модуль без вашей комманды этого не делает.

Проверяйте пингом наличие устройства в зоне действия сети.

 

Brand2
Offline
Зарегистрирован: 25.04.2018

Так оно и есть,модуль же находится в режиме точки доступа с имненем DELTA_unlocker, а телефон ,когда находит эту сеть к ней подключается автоматически,первый раз правда нужно ввести пароль.

Потом он подключается автоматически если видит эту сеть,тут проблемм нет и модуль срабатывает на подключение все время.

А я хочу,что бы он отключал реле когда пропадает соединение ,не зависимо от того,произошло отключение соединения вручную или по причине пропадания сигнала.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Brand2 пишет:



Проблемма начинается ,когда я покидаю зону точки доступа,вижу что на телефоне уже отключился WiFi ,но реле остается включенным,т.е модуль выдает Сonnected,

Когда же я вновь приближаюсь к зоне приема WiFi,получаю Disconnected на секунду примерно и тут же

опять Connected.

Такое впечатление что функция onStationDisconnected не работает при постепенном уменьшении сигнала подключенного вайфая.

Может кто знает почему так происходит?

Это нормальное поведение, имхо. Как вы себе представляете по-другому? Только отошёл от точки доступа - и ТУТ ЖЕ вам прилетело Disconnected? Т.е. кто-то внутри микросхемы потёр хрустальный шар и решил, что это именно дисконнект от точки доступа, а не временные проблемы прохождения сигнала, хотя бы?

Вангую, что если вы будете постепенно отходить от точки доступа - то вы получите свой Disconnected  через какой-то промежуток времени. Какой величины он будет - зависит от многого, но это, опять же имхо - нормальная реализация попыток удержания связи с клиентом.

Если хочется мгновенно прям, и без лишнего софта - лезете в исходники, находите там реализацию стека Wi-Fi, и правите, что хотите - например, выдачу наверх какого-нибудь события по факту, например, неполучения нескольких фреймов подряд.

Brand2
Offline
Зарегистрирован: 25.04.2018

Это сложно пока для моего уровня,хотя была идея контролировать уровень сигнала RSSI и мас адрес,

но тогда возникает проблемма ,когда хочется что бы несколько  телефонов могли  подключатся и отключатся от модуля.

Brand2
Offline
Зарегистрирован: 25.04.2018

Это сложно пока для моего уровня,хотя была идея контролировать уровень сигнала RSSI и мас адрес,

но тогда возникает проблемма ,когда хочется что бы несколько  телефонов могли  подключатся и отключатся от модуля.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ну тогда есть, как минимум, два варианта: либо вы принимаете предложенную событийность в виде "как она есть", либо - свой софт на смартфон, который будет после коннекта к точке доступа периодически слать какой-нибудь пакет. А в прошивке для ESP уже принимать решение - пропущено 5 пакетов (например) - досвидос, дисконнект.

Brand2
Offline
Зарегистрирован: 25.04.2018

Софт для телефона,который бы еще и работал в фоновом режиме,это уже как ядерная физика для меня.

А нельзя ли как нибудь сделать,что бы модуль переодически сам типа разрывал соединение (делал рестарт,сон или что то подобное)и потом снова начинал искать сеть?

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

Brand2 пишет:

Софт для телефона,который бы еще и работал в фоновом режиме,это уже как ядерная физика для меня.

А нельзя ли как нибудь сделать,что бы модуль переодически сам типа разрывал соединение (делал рестарт,сон или что то подобное)и потом снова начинал искать сеть?

Вас пытаются ввести в заблуждение, такой софт в вашем телефоне уже есть, точнее не такой, а нужный вам.

Протокол который вам нужен - ICMP.

Вот вам пример работы этого протокола:

https://yadi.sk/i/ylTw5afc3XFazS

 

Решение вашей проблемы - рассылка пинга всем подключенным довереным устройствам...

Как только устройство(или все устройства) - перестали отвечать на пинг пакеты - они покинули зону действия сети.

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ToRcH2565 пишет:

Brand2 пишет:

Софт для телефона,который бы еще и работал в фоновом режиме,это уже как ядерная физика для меня.

А нельзя ли как нибудь сделать,что бы модуль переодически сам типа разрывал соединение (делал рестарт,сон или что то подобное)и потом снова начинал искать сеть?

Вас пытаются ввести в заблуждение, такой софт в вашем телефоне уже есть, точнее не такой, а нужный вам.

Где я кого вводил в заблуждение? Только разве словосочетанием "свой софт"? И ICMP, кстати - не выход иногда, почему - подумайте на досуге ;) Всё зависит от задачи, в общем.

Ещё раз: я никого не пытался ввести в заблуждение, это вы - клевещете без повода.

Brand2
Offline
Зарегистрирован: 25.04.2018

Спасибо,иду смотреть  .

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Brand2 пишет:

Спасибо,иду смотреть  .

Кстати за пинг: https://github.com/dancol90/ESP8266Ping - библиотечка для ядра ESP в Arduino IDE - чтобы сильно не мучаться с вызовом функций SDK ;)

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

DIYMan пишет:
Где я кого вводил в заблуждение? Только разве словосочетанием "свой софт"?

Ну как бы да, на стороне андроида он не нужен =)

DIYMan пишет:
И ICMP, кстати - не выход иногда, почему - подумайте на досуге ;) Всё зависит от задачи, в общем.

Иногда? зависит от задачи? задача описана, надо отслеживать дисконект. Пинг включен? что будет когда попробуем пинговать девайс вне зоны? правильно или пинга не будет или случится дисконект(и только после дисконекта пинг может пойти на иное устройство которое чудесным образом подключилось чуть позже и получило именно пингуемый айпи).

DIYMan пишет:
Ещё раз: я никого не пытался ввести в заблуждение, это вы - клевещете без повода.

DIYMan пишет:
Ну тогда есть, как минимум, два варианта: либо вы принимаете предложенную событийность в виде "как она есть", либо - свой софт на смартфон, который будет после коннекта к точке доступа периодически слать какой-нибудь пакет.

Вот в этом сообщении, вся вторая часть. Инициатором сообщения может вполне себе быть сервер(WiFi точка) а не клиент(телефон), в таком случае вполне себе спокойно можно обойтись без своего софта на клиенте, достаточно расковырять любой протокол родного софта. Я привел один из тривиальнейших примеров что может выполнить КОНКРЕТНУЮ задачу которую описывал автор, а не как пингом взломать пентагон.

DIYMan пишет:
Всё зависит от задачи, в общем.

Brand2
Offline
Зарегистрирован: 25.04.2018

Если я правильно понял,то ESP должна посылать пинг на подключенный телефон,а он отвечать  ей?

Я не слышал о таких командах у ESP,нельзя ли какой нибудь пример привести здесь?

 

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ToRcH2565 пишет:

Пинг включен?

Вооооттт ;) В правильном направлении идёт мысль, я вижу ;) А так да - можно и ICMP, не вопрос - с этим никто не спорит. Также как с тем, что инициатором в случае описываемой задачи и юзанья ICMP - может быть сам сервер. Возможно, я перестраховываюсь (привычка, выработанная по жизненному опыту), но лично я ни в коем случае не стал бы юзать ICMP и вообще - подходить к решению данной задачи без установления мало-мальски защищённого канала связи.

А так да - решение, предложенное вами, работать будет. Вот только оно насквозь дырявое и наполовину потенциально нерабочее, почему - спросите любого грамотного сисадмина (хотя разговор и за ведроид, но и там с безопасностью постоянно что-то прикручивают).

Вывод: незащищённый канал связи - зло. Вывод №2: каждый ССЗБ, и можно юзать ICMP. Вывод №3: я бы не советовал юзать ICMP, в принципе. Но для решения данной конкретной задачи методом "в лоб" - подходит и ICMP, безусловно.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Brand2 пишет:

Если я правильно понял,то ESP должна посылать пинг на подключенный телефон,а он отвечать  ей?

Я не слышал о таких командах у ESP,нельзя ли какой нибудь пример привести здесь?

Выше я выкладывал ссылку на библиотеку для ESP - она реализует промежуточный слой для вызова функций SDK, ответственных за отсыл и приём пакетов ICMP. Примеры - есть в поставке ;) Пингуете удалённый узел - и если он не отвечает - вышел за пределы действия сети. Или пинг закрыт по соображениям безопасности ;)

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

DIYMan пишет:
Но для решения данной конкретной задачи методом "в лоб" - подходит и ICMP, безусловно.

Вот именно, для решения данной конкретной задачи =)

Про защиту - нислова, ее и не предусматривал.

DIYMan пишет:
но лично я ни в коем случае не стал бы юзать ICMP и вообще - подходить к решению данной задачи без установления мало-мальски защищённого канала связи.

Не вы один, но решение, и направление мысли автора - о защите и не заставляет задумыватся.

DIYMan пишет:
почему - спросите любого грамотного сисадмина

С каких пор у нас сисадмины пишут прошивки китайским модулям? В ведроиде ответ на пинг по умолчанию включен на всех версиях. Есть особо одаренные пользователи рутующие свой телефон и выключающие много чего, но это на их личной совести, я вел речь про стандартные(по умолчанию) настройки и стандартные(по умолчанию) программы.