Добрый день. Скажите пожалуйста кто либо пробовал реализовать данную идею. И на сколько это возможно. Мучаюсь неделю вроде как с рабочим скетчем сервера mqtt. Но возникают проблемы. Спонтанно клиенты перестают конектится к брокеру. Хотя esp не зависает. Пинг идёт, сопутствующие процедуры выполняются. А брокер не отвечает. Подняла брокер на ubuntu там все отлично работает. Но пока не готова покупать малинку или апельсинку под сервер. Если это гиблая идея, так и скажите
Даже не знаю - стоит ли вмешиваться. Блоху когда-то подковали, но развития и практического смысла это не имело. Нужен брокер - коннектесь к iot.eclipse.org.
Это все понятно. Но не хочется привязываться к интернету. Нужно локальный брокер. Который будет висеть на гарантированом питаний.
Тогда я бы посмотрел что-то на дешевом/старом роутере, который допускает перепрошивку на OpenWrt. Понимаю, что опять ответ не по теме, просто хочу помочь.
Зачем же . Просто нужно чтобы брокер был локальный. Чтоб все устройства общались с ним в нутри домашней сети. А он уже как шлюз будет вешать в глобальную сеть все что получает. При подключении интернета.
Библиотека Библиотека umqttbroker.h. Так же установлены часы реального времени и модуль микро сд. На него ведётся лог запросов и ответов.
Вот код брокера: Код (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); }
Какой сакральный смысл копировать данные только для того, чтобы вывести их в 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); }
Вот код клиента: Код (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; } } } }
И тут ошибка: Код (C++): unsigned long CurrentMillis; // Таймер 1 минутный опрос температуры long PreviousMillis = 0; разные типы переменных, для PreviousMillis тоже надо unsigned long.
Забавно, если клиент работает с брокером на убунте и проблем не возникает, получается что "ошибка" уже не считается Наблюдаю похожую проблему на esp32, tcp клиент находится в соединении с сервером, разрыв соединения не предусмотрен сценарием, выполняется двусторонний обмен данными, при очередной попытке выполнить чтение из сокета на клиенте, получаю неожиданно ошибку ECONNRESET 'Tcp Connection reset by peer' в то время как сервер соединение не закрывал и esp не зависает и его можно пинговать.
Ошибку поняла и исправила. Однако когда PreviousMilis был long сбой таймера за сутки не наблюдался. Вообще спустя час телефон не может подкполучи к брокеру. Сейчас попробую на ещё одной есп поднять клиента и подписаться на все топики. Может проблема в по для андроида.
Не чего не решилось, все так же. Трижды перезапустила клиента на есп который получал все топики и он отказался подключаться к брокеру, до тех пор пока не перезагрузила брокера. Наверное библиотека пока сырая для брокера. Запустила тут же брокер на mosquitto опять все без нареканий. Сопутствующий вопрос: как мне посмотреть лог от mosquitto в ubuntu?, где его найти и как открыть. Судя по файлу /etc/mosquitto/conf.d логи должны храниться но не могу их найти и просмотреть. Во вложении скрин conf.d
Послушала Вас. Нашла старый забытый dir300. Залила openwrt. Оказалось мало памяти всего 4 метра. Сейчас собираю свою сборку, исключила все не нужные пакеты. Посмотрю на результат
У меня было такое размышление. Науке известно всего 3-4 брокера, поскольку дело это непростое. Тут с горы выезжает нечто на ESP-8266 , с ее микроскопической памятью. Не должно это работать...
Вы настроили логирование 'log_dest topic' (типа отправляем логи подписчикам, подробнее тут) и пытаетесь найти лог в файле?? Подпишитесь и получайте ваши логи.