Два сервера на esp8266

power
Offline
Зарегистрирован: 29.08.2015

Друзья доброго времени суток! Скажите пожалуйста можно реализовать два сервера на esp8266? один для mqtt другой обычный http:80. Объясню зачем, mqtt для мониторинга и управления выключателями дома а http для управления этим же, только из локалки. Спасибо за ответ.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

power пишет:

Друзья ... можно реализовать два сервера на esp8266? один для mqtt другой обычный http:80.

Лично я - не против. Да и коллеги не звери, думаю разрешат.

Тут, как на свадьбе: если кто против  пусть говорит сейчас или молчит всю жизнь! ;)))))

MakPol
Offline
Зарегистрирован: 03.04.2018

power пишет:

Друзья доброго времени суток! Скажите пожалуйста можно реализовать два сервера на esp8266? один для mqtt другой обычный http:80. Объясню зачем, mqtt для мониторинга и управления выключателями дома а http для управления этим же, только из локалки. Спасибо за ответ.

 

В итоге выяснилось можно (есть такая возможность) или нет? Столкнулся с подобной задачей. HTTP хочу оставить для того, если MQTT накроется или типа того. Пробовал код соединить, т.к. есть и такая и такая реализация, но как то это все странно работало, а скорее не работало ни одно ни другое.

b707
Offline
Зарегистрирован: 26.05.2017

power пишет:

Друзья доброго времени суток! Скажите пожалуйста можно реализовать два сервера     mqtt для мониторинга и управления выключателями дома а http для управления этим же, только из локалки.

я не понял, в чем разница в управлении - один "дома", а другой "из локалки"? Два сервера на одном ESP8266  в разных сетях?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

b707 пишет:

power пишет:

Друзья доброго времени суток! Скажите пожалуйста можно реализовать два сервера     mqtt для мониторинга и управления выключателями дома а http для управления этим же, только из локалки.

я не понял, в чем разница в управлении - один "дома", а другой "из локалки"? Два сервера на одном ESP8266  в разных сетях?

Ну если памяти хватит, за nat’ом почему бы и нет?

MakPol
Offline
Зарегистрирован: 03.04.2018

b707 пишет:

я не понял, в чем разница в управлении - один "дома", а другой "из локалки"? Два сервера на одном ESP8266  в разных сетях?

Два сервера на одном ESP8266  - совершенно верно.  Для работы MQTT нужен интернет или же в локалке сервак типа москито. Летом это не проблема, а зимой на даче может остаться и без интернета, чтобы ходить на тот что в городе и при отключениях света MQTT сервака может не оказаться, а возможность управлять хоть через HTTP слаботочкой нужна. Да и по девайсам, для HTTP в случае чего ничего не надо. Короче необходимость есть и вопрос не в этом надо или нет...

MakPol
Offline
Зарегистрирован: 03.04.2018

BOOM пишет:

Ну если памяти хватит, за nat’ом почему бы и нет?

Скомпилится то скомпилилось, даже кое как работало, но вот взяв за основу управление по HTTP

#include <ESP8266WiFi.h>                      // Подключаем библиотеку ESP8266WiFi
 
const char* ssid = "Название Вашей Сети";     // Название Вашей WiFi сети
const char* password = "Пароль от вашей сети";// Пароль от Вашей WiFi сети

#define RELAY 0                               // Пин к которому подключен датчик
WiFiServer server(80);                        // Указываем порт Web-сервера
 
void setup(){
  delay(2200);      
  Serial.begin(115200);                       // Скорость передачи 115200 
  pinMode(RELAY,OUTPUT);                      // Указываем вывод RELAY как выход
  digitalWrite(RELAY, LOW);                   // Устанавливаем RELAY в LOW (0В)
  Serial.println();                           // Печать пустой строки 
  Serial.print("Connecting to ");             // Печать "Подключение к:"
  Serial.println(ssid);                       // Печать "Название Вашей WiFi сети"
 
  WiFi.begin(ssid, password);                 // Подключение к WiFi Сети
 
  while (WiFi.status() != WL_CONNECTED)       // Проверка подключения к WiFi сети
  { 
    delay(500);                               // Пауза 500 мкс
    Serial.print(".");                        // Печать "."
  }
  Serial.println("");                         // Печать пустой строки  
  Serial.println("WiFi connected");           // Печать "WiFi connected"
 
  server.begin();                             // Запуск сервера
  Serial.println("Server started");           // Печать "Server starte"
  Serial.print("Use this URL to connect: ");  // Печать "Use this URL to connect:" 
  Serial.print(WiFi.localIP());               // Печать выданого IP адресса          
}
 
void loop(){
   WiFiClient client = server.available();    // Получаем данные, посылаемые клиентом 
  if (!client)                                
  {
    return;
  }
  Serial.println("new client");               // Отправка "new client"
  while(!client.available())                  // Пока есть соединение с клиентом 
  {
    delay(1);                                 // пауза 1 мс
  }

  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();
 
  int value = LOW;
  if (request.indexOf("/RELAY=ON") != -1)  
  {
    Serial.println("RELAY=ON");
    digitalWrite(RELAY,LOW);
    value = LOW;
  }
  if (request.indexOf("/RELAY=OFF") != -1)  
  {
    Serial.println("RELAY=OFF");
    digitalWrite(RELAY,HIGH);
    value = HIGH;
  }

  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); 
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<head><title>ESP8266 RELAY Control</title></head>");
  client.print("Relay is now: ");
 
  if(value == HIGH) 
  {
    client.print("OFF");
  } 
  else 
  {
    client.print("ON");
  }
  client.println("<br><br>");
  client.println("Turn <a href=\"/RELAY=OFF\">OFF</a> RELAY<br>");
  client.println("Turn <a href=\"/RELAY=ON\">ON</a> RELAY<br>");
    client.println("</html>");
 
  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");
}

Вкорячить MQTT из стандартного примера уже не вышло

То ли это не реально на есп8266, то ли я наговнокодил

b707
Offline
Зарегистрирован: 26.05.2017

MakPol пишет:

Вкорячить MQTT из стандартного примера уже не вышло

а что не вышло-то? - что-то я в этом коде второго сервера вообще не вижу

MakPol
Offline
Зарегистрирован: 03.04.2018

не работало ничерта и скетч решил нафиг даже не то что не сохранять а удалил. Попробую снова изобразить что сделал. А на основе того что выше в коде, будут работать, если не только на 80 порту сервак а еще 8080 немного другой замутить, к примеру параллельно. Одновременно же не будут работать как понимаю?

 

 

b707
Offline
Зарегистрирован: 26.05.2017

MakPol пишет:

Одновременно же не будут работать как понимаю?

Смотря что понимать под словом "одновременно".

MakPol
Offline
Зарегистрирован: 03.04.2018

подрубился к http а в это время в топике пришли свежие данные, надо выполнить и запостить паблик - что будет с клиентом....

void loop(){
   WiFiClient client = server.available();    // Получаем данные, посылаемые клиентом 
  if (!client)                                
  {
    return;
  }
  Serial.println("new client");               // Отправка "new client"
  while(!client.available())                  // Пока есть соединение с клиентом 
  {
    delay(1);                                 // пауза 1 мс
  }

  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();

Я пошел путем создания для mqtt client1

 

b707
Offline
Зарегистрирован: 26.05.2017

если напишете через while как у вас в строках 8-10 - конечно будет работать только один. Чтоб работали два сервера, для каждого из них надо писать неблокирующий код.

ну или использовать сервера исключительно по очереди :)

MakPol
Offline
Зарегистрирован: 03.04.2018

Значит с неблокирующим облажался. Буду пробовать. Мне понять надо было, что в принципе написать для работы двух возможно. Будем копать...

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

Я не понял - на ЕСП сервер MQTT или клиент?

MakPol
Offline
Зарегистрирован: 03.04.2018

клиент, подписываюсь на топики, ловлю сообщения и выполнив отправляю в топик что выполнено

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

Тогда все правильно (сужу по библиотеке для визнета, правда) - для MQTT отдельный клиент, который не убивается и сервер для HTTP.

MakPol
Offline
Зарегистрирован: 03.04.2018

Собственно то, что я пытаюсь скрестить с примером HTTP и вот что подумал, может проблема в том, что я блокирую при коннекте к mqtt

It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.
/*
 Basic ESP8266 MQTT example
 This sketch demonstrates the capabilities of the pubsub library in combination
 with the ESP8266 board/library.
 It connects to an MQTT server then:
  - publishes "hello world" to the topic "outTopic" every two seconds
  - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary
  - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
    else switch it off
 It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.
 To install the ESP8266 board, (using Arduino 1.6.4+):
  - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
       http://arduino.esp8266.com/stable/package_esp8266com_index.json
  - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
  - Select your ESP8266 in "Tools -> Board"
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "........";
const char* password = "........";
const char* mqtt_server = "broker.mqtt-dashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE	(50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

 

MakPol
Offline
Зарегистрирован: 03.04.2018

Попробовал добавить HTTP в рабочий MQTT и MQTT продолжает работать, а HTTP фиг, потом вижу, что в setup не добавил

server.begin();                             // Запуск сервера
  Serial.println("Server started");           // Печать "Server starte"

добавил и вроде работает все

, буду проверять на отказоустойчивость
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "makpolfy";
const char* password = "pass***";
const char* mqtt_server = "makpol.server.ru";

WiFiServer server(80);                        // Указываем порт Web-сервера
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE  (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and reribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {
 if (!client.connected()) {
    reconnect();
  }
//---------------------------------------------------------------------------------------------------------------------
   WiFiClient client1 = server.available();    // Получаем данные, посылаемые клиентом 
  if (client1)                                
  {
   Serial.println("new client");               // Отправка "new client"
  while(!client1.available())                  // Пока есть соединение с клиентом 
  {
    delay(1);                                 // пауза 1 мс
  }

  String request = client1.readStringUntil('\r');
  Serial.println(request);
  client1.flush();
 
  int value = digitalRead(BUILTIN_LED);
  if (request.indexOf("/BUILTIN_LED=ON") != -1)  
  {
    Serial.println("BUILTIN_LED=ON");
    digitalWrite(BUILTIN_LED,LOW);
    value = LOW;
  }
  if (request.indexOf("/BUILTIN_LED=OFF") != -1)  
  {
    Serial.println("BUILTIN_LED=OFF");
    digitalWrite(BUILTIN_LED,HIGH);
    value = HIGH;
  }

  client1.println("HTTP/1.1 200 OK");
  client1.println("Content-Type: text/html");
  client1.println(""); 
  client1.println("<!DOCTYPE HTML>");
  client1.println("<html>");
  client1.println("<head><title>ESP8266 BUILTIN_LED Control</title></head>");
 // client1.println("<meta http-equiv=\"refresh\" content=\"0;/\">");
  client1.print("BUILTIN_LED is now: ");
 
  if(value == HIGH) 
  {
    client1.print("OFF");
  } 
  else 
  {
    client1.print("ON");
  }
  client1.println("<br><br>");
  client1.println("Turn <a href=\"/BUILTIN_LED=OFF\">OFF</a> BUILTIN_LED<br>");
  client1.println("|<br>");
  client1.println("|<br>");
  client1.println("|<br>");
  client1.println("Turn <a href=\"/BUILTIN_LED=ON\">ON</a> BUILTIN_LED<br>");
    client1.println("</html>");
 
  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");
  }
  //---------------------------------------------------------------------------------------------------------------------

 
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > 10000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg, true);
  }
}