MQTT брокер на базе ESP8266

Тема в разделе "ESP8266, ESP32", создана пользователем Miheeei, 12 окт 2018.

  1. Miheeei

    Miheeei Нерд

    Добрый день. Скажите пожалуйста кто либо пробовал реализовать данную идею. И на сколько это возможно. Мучаюсь неделю вроде как с рабочим скетчем сервера mqtt. Но возникают проблемы. Спонтанно клиенты перестают конектится к брокеру. Хотя esp не зависает. Пинг идёт, сопутствующие процедуры выполняются. А брокер не отвечает. Подняла брокер на ubuntu там все отлично работает. Но пока не готова покупать малинку или апельсинку под сервер. Если это гиблая идея, так и скажите
     
    Последнее редактирование: 12 окт 2018
  2. ИгорьК

    ИгорьК Гуру

    Даже не знаю - стоит ли вмешиваться.
    Блоху когда-то подковали, но развития и практического смысла это не имело.
    Нужен брокер - коннектесь к iot.eclipse.org.
     
  3. Miheeei

    Miheeei Нерд

    Это все понятно. Но не хочется привязываться к интернету. Нужно локальный брокер. Который будет висеть на гарантированом питаний.
     
  4. ИгорьК

    ИгорьК Гуру

    Тогда я бы посмотрел что-то на дешевом/старом роутере, который допускает перепрошивку на OpenWrt.
    Понимаю, что опять ответ не по теме, просто хочу помочь.
     
    DIYMan нравится это.
  5. Mitrandir

    Mitrandir Гуру

    Вы ставите под сомнение профессионализм энергетиков датацентров эклипса??
     
  6. FreeDIY

    FreeDIY Нуб

    Смысл, похоже, в том, что человеку нужен именно локальный брокер)
     
  7. Miheeei

    Miheeei Нерд

    Зачем же . Просто нужно чтобы брокер был локальный. Чтоб все устройства общались с ним в нутри домашней сети. А он уже как шлюз будет вешать в глобальную сеть все что получает. При подключении интернета.
     
  8. ZAZ-965

    ZAZ-965 Гуру

    @Miheeei, какую библиотеку применяете? На ESP8266 что-то еще дополнительно работает, кроме брокера?
     
  9. Miheeei

    Miheeei Нерд

    Библиотека
    Библиотека umqttbroker.h.
    Так же установлены часы реального времени и модуль микро сд. На него ведётся лог запросов и ответов.
     
  10. Miheeei

    Miheeei Нерд

    Вот код брокера:
    Код (C++):
    //Wifi
    #include <ESP8266WiFi.h>
    #define Wifi_Ssid "_-BNG-MX-_"
    #define Wifi_Pass "kz733cfa03"
    //MQTT
    #include "uMQTTBroker.h"
    uMQTTBroker myBroker;
    //------------------------------
    void data_callback(uint32_t *client /* we can ignore this */, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh)
    {
      // Отоброжение топика
      char topic_str[topic_len+1];
      os_memcpy(topic_str, topic, topic_len);
      topic_str[topic_len] = '\0';
      // Отображения значения топика
      char data_str[lengh+1];
      os_memcpy(data_str, data, lengh);
      data_str[lengh] = '\0';
      // Вывод в сериал порт полученых данных
      Serial.print("received topic => ");
      Serial.print(topic_str);
      Serial.print(" | with data => ");
      Serial.println(data_str);
    }
    //------------------------------

    void setup()
    {
      Serial.begin(9600);
      Serial.println();
      Serial.println("Connecting to "+(String)Wifi_Ssid);
      WiFi.begin(Wifi_Ssid, Wifi_Pass);
      WiFi.config(IPAddress (192,168,1,100), IPAddress (192,168,1,1), IPAddress (255,255,255,0));
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("Sever IP address: " + WiFi.localIP().toString());
      Serial.println("Starting MQTT broker");
      myBroker.init();
      MQTT_server_onData(data_callback);
      MQTT_local_subscribe((unsigned char *)"#", 0);
    }

    void loop()
    {
      delay(1000);
    }
     
  11. DIYMan

    DIYMan Guest

    Какой сакральный смысл копировать данные только для того, чтобы вывести их в Serial? Вот эту простыню:
    Код (C++):
    void data_callback(uint32_t *client /* we can ignore this */, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh)
    {
      // Отоброжение топика
      char topic_str[topic_len+1];
      os_memcpy(topic_str, topic, topic_len);
      topic_str[topic_len] = '\0';
      // Отображения значения топика
      char data_str[lengh+1];
      os_memcpy(data_str, data, lengh);
      data_str[lengh] = '\0';
      // Вывод в сериал порт полученых данных
      Serial.print("received topic => ");
      Serial.print(topic_str);
      Serial.print(" | with data => ");
      Serial.println(data_str);
    }
    можно сократить до:
    Код (C++):
    void data_callback(uint32_t *client /* we can ignore this */, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh)
    {
      Serial.print("received topic => ");
      Serial.print(topic);
      Serial.print(" | with data => ");
      Serial.println(data);
    }
     
  12. Miheeei

    Miheeei Нерд

    Вот код клиента:
    Код (C++):
    \\ds18b20
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS 5
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    // WIFI
    #include <ESP8266WiFi.h>
    #define Wifi_SSID "_-BNG-MX-_"
    #define Wifi_PASS "kz733cfa03"
    // MQTT
    #include <PubSubClient.h>
    const char *mqtt_server = "192.168.1.100"; // Имя сервера MQTT
    const int mqtt_port = 1883; // Порт для подключения к серверу MQTT
    const char *mqtt_user = "Login"; // Логи от сервер
    const char *mqtt_pass = "Pass"; // Пароль от сервера
    WiFiClient wclient;
    PubSubClient client(wclient, mqtt_server, mqtt_port);

    //ТАЙМЕР в 30 сек
    unsigned long CurrentMillis;                        
    // Таймер 1 минутный опрос температуры
    long PreviousMillis = 0;                          
    long Interval = 30000;  


    /////////////////////////////////////////////////////////////////////////////////////////////////////
    void WifiConect()// Подключения к WiFi
    {
      Serial.print("# Network WiFi conection..");
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("# WiFi connected | IP address: " + WiFi.localIP().toString());
    }
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    void Temperatura()
    {
      sensors.setWaitForConversion(false);
      sensors.requestTemperatures();   // от датчика получаем значение температуры
      float temp = sensors.getTempCByIndex(0);
      client.publish("Temp",String(temp,1)); // отправляем в топик для термодатчика значение температуры
      Serial.println("Server send Temperature = " + String(temp,1) + " C");
    }

    void setup()
    {
      Serial.begin(9600);
      sensors.begin();
      Serial.println();
      WiFi.begin(Wifi_SSID, Wifi_PASS);
      //WiFi.config(IPAddress (192,168,1,111), IPAddress (192,168,1,1), IPAddress (255,255,255,0));
      WifiConect();
      pinMode(2, OUTPUT);
    }

    void loop()
    {
      CurrentMillis = millis();
      // подключаемся к MQTT серверу
      if (WiFi.status() == WL_CONNECTED)
      {
        if (!client.connected())
        {
          Serial.println("Connecting to SmartHome server...");
          if (client.connect(MQTT::Connect("ds18b20").set_auth(mqtt_user, mqtt_pass)))
          {
            Serial.println("Server Connected");
          }
          else
          {
            Serial.println("Not connect server");  
          }
        }
        if (client.connected())
        {
          client.loop();
          if(CurrentMillis - PreviousMillis > Interval)
          {
            Temperatura();
            PreviousMillis = CurrentMillis;
          }
        }  
      }
    }
     
  13. DIYMan

    DIYMan Guest

    И тут ошибка:
    Код (C++):
    unsigned long CurrentMillis;                        
    // Таймер 1 минутный опрос температуры
    long PreviousMillis = 0;    
    разные типы переменных, для PreviousMillis тоже надо unsigned long.
     
  14. Забавно, если клиент работает с брокером на убунте и проблем не возникает, получается что "ошибка" уже не считается :)
    Наблюдаю похожую проблему на esp32, tcp клиент находится в соединении с сервером, разрыв соединения не предусмотрен сценарием, выполняется двусторонний обмен данными, при очередной попытке выполнить чтение из сокета на клиенте, получаю неожиданно ошибку ECONNRESET 'Tcp Connection reset by peer' в то время как сервер соединение не закрывал и esp не зависает и его можно пинговать.
     
  15. Miheeei

    Miheeei Нерд

    Ошибку поняла и исправила. Однако когда PreviousMilis был long сбой таймера за сутки не наблюдался.
    Вообще спустя час телефон не может подкполучи к брокеру. Сейчас попробую на ещё одной есп поднять клиента и подписаться на все топики. Может проблема в по для андроида.
     

    Вложения:

  16. Miheeei

    Miheeei Нерд

    Не чего не решилось, все так же. Трижды перезапустила клиента на есп который получал все топики и он отказался подключаться к брокеру, до тех пор пока не перезагрузила брокера. Наверное библиотека пока сырая для брокера. Запустила тут же брокер на mosquitto опять все без нареканий. Сопутствующий вопрос: как мне посмотреть лог от mosquitto в ubuntu?, где его найти и как открыть.
    Судя по файлу /etc/mosquitto/conf.d логи должны храниться но не могу их найти и просмотреть.
    Во вложении скрин conf.d
     

    Вложения:

  17. Miheeei

    Miheeei Нерд

    Послушала Вас. Нашла старый забытый dir300. Залила openwrt. Оказалось мало памяти всего 4 метра. Сейчас собираю свою сборку, исключила все не нужные пакеты. Посмотрю на результат
     
    ZAZ-965 нравится это.
  18. ИгорьК

    ИгорьК Гуру

    У меня было такое размышление. Науке известно всего 3-4 брокера, поскольку дело это непростое.
    Тут с горы выезжает нечто на ESP-8266 , с ее микроскопической памятью.
    Не должно это работать...
     
  19. Вы настроили логирование 'log_dest topic' (типа отправляем логи подписчикам, подробнее тут) и пытаетесь найти лог в файле??
    Подпишитесь и получайте ваши логи.
     
  20. А те у кого заработал пирмер uMQTTBrokerSample вообще изгои.