• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Как отправлять сообщения в топик с флагом Retain (программирую в среде Ардуино)

prygunovdn

New member
Помогите пожалуйста разобраться. Как отправить сообщение командой
Код:
client.publish(prefix + "/vorota1", "0");
чтобы она хранилась на сервере. Нужно как то поставить флаг Retain. Приложение я использую mqttLiner. В нем я перевожу переключатель в режим включено и затем МК его через секунду переводит в положение выключено(так и задумано). Затем я закрываю приложение, открываю его заново, а там ползунок находится в режиме включено, хотя на МК все выключено. Я так понял это из за того что приложение ставит флаг а МК при переводе в выключено не ставит. Как его поставить с МК? Уже всю голове сломал. Программа управляет освещением и двумя воротами.
Код:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2 //датчик даллас подключен на GPIO 2 (pin d4)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
const int svet1 =  12;      // Свет на улице перед гаражем на GPIO 12 (pin d6)
const int svet2 =  13;      // Свет на улице перед гаражем на GPIO 13 (pin d7)
const int svet3 =  14;      // Свет на улице перед гаражем на GPIO 14 (pin d5)
const int vorota1 =  5;      // Открытие ворот 1 GPIO 5 (pin d1)
const int vorota2 =  4;      // Открытие ворот 2 GPIO 4 (pin d2)
const int vorota1stat =  0;      // состояние ворот гаража  GPIO 15 (pin d8)
int vorotablok = 0; // переменная состояния блокировки ворот
int passblok = 1987;// пороль для ворот
//int svet3ok = 0 ;
String prefix   = "dom1"; //префикс всех топиков данного устройства
const char *ssid = ""; // Имя вайфай точки доступа
const char *pass = ""; // Пароль от точки доступа

const char *mqtt_server = ""; // Имя сервера MQTT
const int mqtt_port = ; // Порт для подключения к серверу MQTT
const char *mqtt_user = ""; // Логи от сервер
const char *mqtt_pass = ""; // Пароль от сервера
long previousMillis = 0;        // для функции онлайн
int ledState = LOW;// для функции онлайн
long interval = 1000;           // для функции онлайн
boolean retained = true;
#define BUFFER_SIZE 100

//bool LedState = false;
int tm=300; //задержка отправки показаний
int onl=20; //задержка миганий для онлайна
float temp=0; // переменная для температуры
int stled = 0; //переменная в которую получаем
int stledv = 0; //переменная в которую получаем ворота 1 и 2
int stled1 = 0; // храним значение для задержки ворот 1
int stled11 = 0; // храним значение для задержки ворот 1 что их включили
int stled2 = 0; // храним значение для задержки ворот 2
int stled22 = 0; // храним значение для задержки ворот 2 что их включили
int stsvet3;
WiFiClient wclient;
PubSubClient client(wclient, mqtt_server, mqtt_port);

// Функция получения данных от сервера

void callback(const MQTT::Publish& pub)
{
Serial.print(pub.topic()); // выводим в сериал порт название топика
Serial.print(" => ");
Serial.print(pub.payload_string()); // выводим в сериал порт значение полученных данных

String payload = pub.payload_string();
// Обработка топика svet1
if(String(pub.topic()) == prefix + "/svet1") // проверяем из нужного ли нам топика пришли данные
{
stled = payload.toInt(); // преобразуем полученные данные в тип integer
if (stled == 1)
{digitalWrite(svet1, HIGH);}
if (stled == 0)
{digitalWrite(svet1, LOW); }
}
// Обработка топика vorotablok
if(String(pub.topic()) == prefix + "/vorotablok") // проверяем из нужного ли нам топика пришли данные
{
vorotablok = payload.toInt(); // преобразуем полученные данные в тип integer
}
// Обработка топика svet2
if(String(pub.topic()) == prefix + "/svet2") // проверяем из нужного ли нам топика пришли данные
{
stled = payload.toInt(); // преобразуем полученные данные в тип integer
if (stled == 1)
{digitalWrite(svet2, HIGH); }
if (stled == 0)
{digitalWrite(svet2, LOW); }
}
// Обработка топика svet3
if(String(pub.topic()) == prefix + "/svet3") // проверяем из нужного ли нам топика пришли данные
{
stsvet3 = payload.toInt(); // преобразуем полученные данные в тип integer
if (stsvet3 == 1)
{digitalWrite(svet3, HIGH); }
if (stsvet3 == 0)
{digitalWrite(svet3, LOW); }
}
//Serial.println(stled1);// + "do topika vorota1");
// Обработка топика vorota1
if(String(pub.topic()) == prefix + "/vorota1") // проверяем из нужного ли нам топика пришли данные
{
stledv = payload.toInt(); // преобразуем полученные данные в тип integer
Serial.print("stledv");
Serial.println(stledv);
if (stledv == 1)
{stled1 = 1;
stledv = 0;}} // сохраняем нажатие ворота 1
//else
//{client.publish("domm/domm", "VOROTA ZAPRET");}

// Обработка топика vorota2
if(String(pub.topic()) == prefix + "/vorota2") // проверяем из нужного ли нам топика пришли данные
{
stledv = payload.toInt(); // преобразуем полученные данные в тип integer
if (stledv == 1)
{stled2 = 1;
stledv = 0;}} // сохраняем нажатие ворота 1
//if (stled == 1)
//{digitalWrite(vorota2, HIGH);
//delay (200);
//digitalWrite(vorota2, LOW);
//client.publish(prefix + "/vorota2", "0");
//client.publish(prefix + "/vorota2", "Жопа");
//stled = 0;
//}
//if (stled == 0)
//{digitalWrite(vorota2, LOW); }
}


void setup() {

sensors.begin();
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
pinMode(svet1, OUTPUT);
pinMode(svet2, OUTPUT);
pinMode(svet3, OUTPUT);
pinMode(vorota1, OUTPUT);
pinMode(vorota2, OUTPUT);
pinMode(vorota1stat, INPUT);
//client.publish(prefix + "/vorota2", "0");
//client.publish(prefix + "/vorota1", "0");
digitalWrite(vorota1, LOW);
digitalWrite(vorota2, LOW);
//digitalWrite(svet3, LOW);
//Serial.println(stled1);// + "posle initcializacii");
}

void loop() {
// подключаемся к wi-fi
if (WiFi.status() != WL_CONNECTED) {
Serial.print("Connecting to ");
Serial.print(ssid);
Serial.println("...");
WiFi.begin(ssid, pass);

if (WiFi.waitForConnectResult() != WL_CONNECTED)
return;
Serial.println("WiFi connected");
}

// подключаемся к MQTT серверу
if (WiFi.status() == WL_CONNECTED) {
if (!client.connected()) {
Serial.println("Connecting to MQTT server");
if (client.connect(MQTT::Connect("arduinoClient3") // имя клиента индивидуальное
.set_auth(mqtt_user, mqtt_pass))) {
Serial.println("Connected to MQTT server");
//client.publish(prefix + "/vorota2", "0");
//client.publish(prefix + "/vorota1", "0");

client.set_callback(callback);
client.subscribe(prefix + "/svet3"); // подписывааемся по топик с данными
client.subscribe(prefix + "/svet2"); // подписывааемся по топик с данными
client.subscribe(prefix + "/svet1"); // подписывааемся по топик с данными
client.subscribe(prefix + "/vorota1"); // подписывааемся по топик с данными
client.subscribe(prefix + "/vorota2"); // подписывааемся по топик с данными
client.subscribe(prefix + "/vorotablok");
client.subscribe(prefix + "/vorota1stat");
} else {
Serial.println("Could not connect to MQTT server");
}}
if (client.connected()){
client.loop();
//TempSend();
online();

}}} // конец основного цикла



// Функция ONLINE
void online(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
if (ledState == LOW)
     { ledState = HIGH;
      client.publish(prefix + "/online", "1");
      //Serial.println(stled1);// + "pered  if (stled1 == 1 && vorotablok == passblok )");
      if (stled1 == 1 && vorotablok == passblok ) //задержка нажатия ворот1 если было нажатие
  {digitalWrite(vorota1, HIGH); //окрываем ворот1
  stled11 = 1;} //фиксируем что включили ворот1
// Serial.println(stled1);// + "pered if (stled1 == 1 && stled11 == 0 && vorotablok != passblok)");
if (stled1 == 1 && stled11 == 0 && vorotablok != passblok)
{//client.publish("domm/domm", " ");
client.publish("domm/domm", "Ворота гараж ЗАПРЕТ");
client.publish(prefix + "/vorota1", "0");
stled1 = 0;}
  if (stled2 == 1 && vorotablok == passblok ) //задержка нажатия ворот1 если было нажатие
  {digitalWrite(vorota2, HIGH); //окрываем ворот2
  stled22 = 1;} //фиксируем что включили ворот2
  if (stled2 == 1 && stled22 == 0 && vorotablok != passblok)
{//client.publish("domm/domm", " ");
client.publish("domm/domm", "Ворота Откатные ЗАПРЕТ");
client.publish(prefix + "/vorota2", "0");
stled2 = 0;}

      // Отправка состояния ворот
      if (digitalRead(vorota1stat)== 0)
      {client.publish(prefix + "/vorota1stat","Открыто");}
      else
      {client.publish(prefix + "/vorota1stat","Закрыто");}
     // Serial.println(digitalRead(vorota1stat));
      // Конец Отправка состояния ворот
   
      sensors.requestTemperatures(); // от датчика получаем значение температуры
float temp = sensors.getTempCByIndex(0); // преобразуем
client.publish(prefix + "/temp",String(temp));} // отправляем
    else
     { ledState = LOW;
      client.publish(prefix + "/online", "0");

     // if (vorotablok == 0)
      //{
       //client.publish(prefix + "/vorota1", "0");
       //client.publish(prefix + "/vorota2", "0");}
   
      if (stled1 == 1 && stled11 == 1 ) //задержка нажатия ворот1
     { digitalWrite(vorota1, LOW); //задержка нажатия ворот1
stled1 = 0; //задержка нажатия ворот1 само нажатие
stled11 = 0;//задержка нажатия ворот1 что было нажатие
client.publish(prefix + "/vorota1", "0");}

if (stled2 == 1 && stled22 == 1 ) //задержка нажатия ворот2
     { digitalWrite(vorota2, LOW); //задержка нажатия ворот2
stled2 = 0; //задержка нажатия ворот2 само нажатие
stled22 = 0;//задержка нажатия ворот2 что было нажатие

client.publish(prefix + "/vorota2", "0");}
}
      }}
Retain нужно добавить в этой части кода.
Код:
  if (stled1 == 1 && stled11 == 1 ) //задержка нажатия ворот1
     { digitalWrite(vorota1, LOW); //задержка нажатия ворот1
stled1 = 0; //задержка нажатия ворот1 само нажатие
stled11 = 0;//задержка нажатия ворот1 что было нажатие
client.publish(prefix + "/vorota1", "0");} //ЭТО СООБЩЕНИЕ ДОЛЖНО БЫТЬ С РЕТЕЙН
 
Последнее редактирование:

prygunovdn

New member
Нашел такой вариант
Код:
client.publish(MQTT::Publish(prefix + "/vorota1", "0").set_retain(1));
Вроде как все теперь правильно работает.
Только вот без этого (MQTT::publish) не компилировалось. Если кто то знает подробнее поясните пожалуйста.
 

Paratrooper

New member
Нашел такой вариант
Код:
client.publish(MQTT::Publish(prefix + "/vorota1", "0").set_retain(1));
Вроде как все теперь правильно работает.
Только вот без этого (MQTT::publish) не компилировалось. Если кто то знает подробнее поясните пожалуйста.
Достаточно этого:
Код:
client.publish(prefix + "/vorota1", "0", true);
 
Сверху Снизу