Cloudmqtt - значения не сохраняются на сервере

Shadow77
Offline
Зарегистрирован: 10.01.2016

Здравствуйте!

Такая проблема. Есть плата ESP8266, прошитая через Arduino IDE.

В программе используется стандартная библиотека PubSubClient.h

Проблема в том, что значения на CloudMQTT приходят, их можно наблюдать в recieved messages на сайте или со смартфона. НО, только, когда они приходят в реальном времени. Т.е. окно браузера открыто или смартфон подключен, а на сервере они не остаются и не сохраняются.

Если я только что подключился, мне надо ждать, пока придут данные.

До этого прошивал модуль прошивкой wifi-iot - данные с него до сих пор висят на сервере.

Что я делаю не так??? Подскажите хотя бы в какую сторону копать, т.к. информации по этому поводу я негде не нашел.

kpmsk
Offline
Зарегистрирован: 13.10.2016

У меня точно такой вопрос. Данные с датчиков прилетают на cloudmqtt.com. В приложении mqtt dashboard я их вижу. Даже графики строятся. Но стоит выйти из приложения, данные исчезают. Т.е. не сохраняются. В чем дело ? Может, так сказать, система не предназначена.. ? Или.. ?

Алексей.
Offline
Зарегистрирован: 02.02.2018

Нормальное поведение если публикатор не устанавливает retain флаг, клиенты, даже если они надежные (имеют id) и подписывались на топик не получат его если были в оффлайне в момент публикации.

Устанавливайте retain

If retain is given, the message will be retained as a "last known good" value on the broker.

и будет вам счастье, подробно тут раздел Retained Messages

kpmsk
Offline
Зарегистрирован: 13.10.2016

Спасибо за направление. 

Посмотрел доступное описание к версии библиотеки которую я использую - https://github.com/Imroy/pubsubclient

прописал у себя 

 client.publish(MQTT::Publish("temp", String(temp))
                  .set_qos(2)
                  .set_retain(true)
              //  .set_dup()
               );
 
 
в set_retain указал true
 
но значения датчика так и не сохраняются в cloudmqtt..
что-то я опять не догоняю.. ?
 
 
 

 

Алексей.
Offline
Зарегистрирован: 02.02.2018

У нас всё работает ;-)
Я пользуюсь библиотекой https://github.com/knolleary/pubsubclient, на хабе у неё звезд 1782 ;-)
Вы пользуетесь https://github.com/Imroy/pubsubclient, звезд у нее поменьше, 362, да и последний коммит более года назад, если авторы библиотеку уже не пилят - значит с кодом всё хорошо или к коду пропал интерес. Взглянув на звезды я решил действовать по старинке (выбрал то что выбирают большинство пользователей).
Вы используете другую библиотеку, это ваш выбор, продолжайте экспериментировать.

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

static const char _ssid[] = "your_wifi_ssid";
static const char _psk[] = "your_wifi_password";
static const char _user[] = "your_mqtt_login";
static const char _pass[] = "your_mqtt_password";
static const char _server[] = "m21.cloudmqtt.com";
static int _port = 16380;

void setup() {
    WiFiClient wifi_client;
    PubSubClient mqtt_client(wifi_client);
    Serial.begin(115200);
    Serial.println("");

    WiFi.mode(WIFI_STA);
    WiFi.begin(_ssid, _psk);
    if (WiFi.getAutoConnect() == false) {
        WiFi.persistent(true);
        WiFi.setAutoConnect(true);
        WiFi.persistent(false);
    }
    WiFi.setAutoReconnect(true);
    
    Serial.print("connecting to wifi ");
    Serial.println(_ssid);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
    }
    Serial.println("wifi connected");

    mqtt_client.setServer(_server, _port);

    char my_id[32];
    uint8_t mac[6];
    WiFi.macAddress(mac);
    sprintf(my_id, "esp-%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    Serial.print("connecting to mqtt broker ");
    Serial.println(_server);
    while (!mqtt_client.connected()) {
        if (mqtt_client.connect(my_id, _user, _pass)) {
            Serial.println("mqtt connected");
            mqtt_client.publish("my-test-no-retain", my_id);
            mqtt_client.publish("my-test-retained", my_id, true);
        } else {
            delay(500);
            Serial.println("mqtt connect failed");
        }
    }

    Serial.println("test is done");
    while (1) {
        delay(500);
    }
}

void loop() {
}

 

Алексей.
Offline
Зарегистрирован: 02.02.2018

Для тестов я на cloudmqtt.com зарегился, создал инстанс с бесплатным тарифом, выбрал расположение в Европе и получил логин/пароль имя сервера m21.cloudmqtt.com и порт сервера, но с m21.cloudmqtt.com (домен резолвется на адрес 34.251.42.52) соединится не просто, РКН немножко блокирует доступ к ip адресам амазона, на сервисах которого и поднят этот инстанс.
Статья 15.3 Реквизиты основания внесения в реестр - Генпрокуратура 27-31-2018/Ид2971-18 16.04.2018
Не ужели к cloudmqtt.com ещё не пропал интерес???
 

kpmsk
Offline
Зарегистрирован: 13.10.2016

Алексей, по -быстрому исправил свой код для использования с той же библиотекой, которую указали вы. 

Прописал, чтобы значения с датчика сохранялись на mqtt сервере, указал как в примере: 

mqtt_client.publish("my-test-retained", my_id, true);

В итоге показания с датчика прилетают на на cloudmqtt, через мобильное приложение вижу прилетевшие значения, по ним опять же даже строится график, но стоит выйти из моб. приложения MQTT Dashboard и зайти в него вновь, все ранее полученные значения исчезли (не сохранились).  Ровно такая же ситуация была и с той библиотекой которую я использовал до того как вы мне написали что с другой библиотекой у вас все ок. Что может быть не так, не пойму..

 

kpmsk
Offline
Зарегистрирован: 13.10.2016

Алексей. пишет:

Не ужели к cloudmqtt.com ещё не пропал интерес???

А что, есть что-либо более лучшее, удобнее, функциональнее..?  Чем обусловлена такая постановка вопроса ? Если не считать того, что сервис живет на амазоне, чьи ip у нас могут быть заблок рованы

В моем случае, я просто тестирую(изучаю) работу через mqtt. Для тестов нужен mqtt сервер (брокер). Самое простое и быстрое для этого использовать именно cloudmqtt.com. Но вот не пойму, почему значения датчика при публикации с установленным в true флагом retained не сохраняются на сервере. А мне нужно чтобы значения сохранялись и накапливались на сервере.

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

Так может вы на тарифном плане, который не предусматривает сохранение данных.

kpmsk
Offline
Зарегистрирован: 13.10.2016

Почитал тут (https://www.hivemq.com/blog/mqtt-essentials-part-4-mqtt-publish-subscribe-unsubscribe). Нашел:

Retain Flag
This flag defines whether the message is saved by the broker as the last known good value for a specified topic. When a new client subscribes to a topic, they receive the last message that is retained on that topic. For details on retained messages, see part 8 of MQTT Essentials.
 
Т.е. получается если retained = true, то на сервере сохраняется последнее "good value" от датчика. Т.е. установкa  флага retained в true  не включает сохранение всех приходящих на сервер значений от датчика.. :-(
Алексей.
Offline
Зарегистрирован: 02.02.2018

All messages may be set to be retained. This means that the broker will keep the message even after sending it to all current subscribers. If a new subscription is made that matches the topic of the retained message, then the message will be sent to the client. This is useful as a "last known good" mechanism.

Именно таким образом, на датчике температуры, который просыпается на 5 сек. раз в 30 минут, я публикую измеренное значение температуры, влажности и напряжение батарейки, от которой работает esp8266, а клиентом получаю всегда последний пайлоад этого топика, не зависимо находился ли клиент в офлайне в момент публикации. Более того, пока клиент получивший этот топик, сам его не удалит, каждый раз подключаясь к брокеру, будет получать его.
Не забывайте у клиента, который подписывается на топик, устанавливать client_id (один и тотже, а не каждый раз новый)

Алексей.
Offline
Зарегистрирован: 02.02.2018

sadman41 пишет:

Так может вы на тарифном плане, который не предусматривает сохранение данных.

У меня получилось на бесплатном, не думаю что на платных этого нет, да и дешевле бесплатного у данного провайдера тоже нет.