Правильный способ создания оператора IF с использованием данных из обратного вызова mqtt - PullRequest
0 голосов
/ 30 марта 2019

Я пытаюсь вызвать действие, используя вывод функции обратного вызова в моем коде.По сути, у меня будет датчик двери на «reedTopic», который должен сообщить «ВЫКЛ», прежде чем разрешить отправку полезной нагрузки для «темы».Полезная нагрузка "topic" - это переключатель для устройства открывания гаражных ворот, поэтому данные из "topic" всегда будут оставаться неизменными.

Цель заключается в том, чтобы подключенный к моей машине esp8266-01 подключался кбеспроводной сети, он обнаружит состояние «reedTopic» и, если он не равен «OFF», не вызовет полезную нагрузку «theme».

Я хочу полностью настроить эту автоматизацию в коде ине нужно полагаться на дополнительное программное обеспечение, такое как Node-Red или HomeAssistant, для выполнения этой работы.

Я также почти уверен, что не до конца понимаю функцию обратного вызова и то, как она должна использоваться,особенно в этом случае.Я все еще немного новичок в Arduino, так что это действительно мой первый проект.Я также почти уверен, что там есть какой-то мусорный код, так как большая часть кода была собрана из примеров в Arduino IDE для обработчика pubsubclient.

#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>

const char* ssid = "******";
const char* password = "******";
const char* host = "CarPresence";
const char* update_path = "/";
const char* update_username = "*****";
const char* update_password = "*****";

char* topic = "cmnd/GarageDoor/POWER";
const char* willTopic = "cmnd/GarageDoor/POWER";
char* reedTopic = "cmnd/GarageDoor/POWER2";
char* server = "192.168.1.138";
byte willQoS = 1;
const char* willMessage = "1";
boolean willRetain = false;
boolean retained = true;

ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
WiFiClient wifiClient;
PubSubClient client(server, 1883, wifiClient);

void callback(char* reedTopic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
 Serial.print(reedTopic);
 Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
 }
 if (strcmp((char* )reedTopic, "OFF") == 0) {
  client.connect("CarPresence", willTopic, willQoS, willRetain, willMessage);
    client.publish(topic, "The Garage door is CLOSED... Opening...");
    client.publish(topic, "1");
    while (WiFi.status() == WL_CONNECTED) {
    delay(5000);
    client.println(reedTopic);
    client.publish(topic, "Ah ah ah ah staying alive staying alive...");
    }
    }
  if (strcmp((char* )reedTopic, "ON") == 0) {
    client.publish(topic, "The Garage door is OPEN... Aborting...");
    while (WiFi.status() == WL_CONNECTED) {
    delay(5000);
    client.println(reedTopic);
    client.publish(topic, "Dying... I'm dying...");
    }
  }
  Serial.println();
  }

String macToStr(const uint8_t* mac)
{
  String result;
  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);
    if (i < 5)
      result += ':';
  }
  return result;
}

void setup() {
  Serial.begin(115200);
  delay(10);

client.setCallback(callback);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  client.connect("CarPresence");
  client.subscribe(topic);
  client.subscribe(reedTopic, retained);
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  httpUpdater.setup(&httpServer, update_path, update_username, update_password);
  httpServer.begin();

  Serial.printf("HTTPUpdateServer ready! Open http://%s%s in your browser and login with username '%s' and password '%s'\n", host, update_path, update_username, update_password);

  // Generate client name based on MAC address and last 8 bits of microsecond counter
  String clientName = "CarPresence";

  Serial.print("Connecting to ");
  Serial.print(server);
  Serial.print(" as ");
  Serial.println(clientName);

  if (client.connect((char*) clientName.c_str())) {
    Serial.println("Connected to MQTT broker");
    Serial.print("Topics are: ");
    Serial.println(topic);
    Serial.println(reedTopic);

    if (client.publish(topic, "Hello from ESP8266")) {
      Serial.println("Publish ok");
    }
    else {
      Serial.println("Publish failed");
    }
  }
  else {
    Serial.println("MQTT connect failed");
    Serial.println("Will reset and try again...");
    abort();
  }
}

void loop() {

  httpServer.handleClient();
  client.setCallback(callback);

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

По большей части код работает.Самая большая проблема - это утверждение IF о обратной связи reedTopic.Код проносится мимо него и выполняет полезную нагрузку темы без второго взгляда.

1 Ответ

0 голосов
/ 04 апреля 2019

Мне удалось получить некоторую помощь от автора PubSubClient на GitHub.Позже я нашел остальное, что мне было нужно на форумах Arduino.Вот мой законченный код ниже.

// Setup your sonoff                                                      //
// Flash your sonoff switch with tasmota                                  //
// Associate the tasmotized sonoff with your WiFi network                 //
// Load the webpage for the sonoff and setup your mqtt topics             //
// Go into module setup and set GPIO14 to Switch2                         //
// Go into the console and type "SwitchMode2 1" (without quotes)          //
// Lastly, in the console type "PulseTime 1" (without quotes)             //

// Setup credentials in the code                                          //
// Replace asterisks next to ssid & password with WiFi credentials        //
// Replace asterisks next to update_username & update_password with creds //

#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>

const char* ssid = "******";
const char* password = "******";
const char* host = "CarPresence";
const char* update_path = "/";
const char* update_username = "******";
const char* update_password = "******";

char* topic = "cmnd/GarageDoor/POWER";
const char* willTopic = "cmnd/GarageDoor/POWER";
char* reedTopic = "cmnd/GarageDoor/POWER2";
char* server = "192.168.1.138";
byte willQoS = 1;
const char* willMessage = "1";
boolean willRetain = false;
boolean retained = true;

ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
WiFiClient wifiClient;
PubSubClient client(wifiClient);

void reconnect() {
 // Loop until we're reconnected
 while (!client.connected()) {
 Serial.print("Attempting MQTT connection...");
 // Attempt to connect
 if (client.connect("CarPresence")) {
  Serial.println("connected");
  // set callback and subscribe to topics
  client.setCallback(callback);
  client.subscribe("cmnd/GarageDoor/POWER");
  client.subscribe("cmnd/GarageDoor/POWER2");
 } else {
  Serial.print("failed, rc=");
  Serial.print(client.state());
  Serial.println(" try again in 5 seconds");
  // Wait 5 seconds before retrying
  delay(5000);
  }
 }
}

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

  if(message == "ON"){
    client.publish(topic, "Garage Door is CLOSED");
    client.publish(topic, "1");
    delay(10000);
    while(message != "ON"){
    break;
    }
  } 
  if(message == "OFF"){
    client.publish(topic, "Garage Door is OPEN");
    delay(10000);
    while(message != "OFF"){
      break;
    }
  }
}

String macToStr(const uint8_t* mac)
{
  String result;
  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);
    if (i < 5)
      result += ':';
  }
  return result;
}

void setup() {
  Serial.begin(115200);
  delay(10);

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

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

  httpUpdater.setup(&httpServer, update_path, update_username, update_password);
  httpServer.begin();

  Serial.println("HTTPUpdateServer ready!");

  // Generate client name based on MAC address and last 8 bits of microsecond counter
  String clientName = "CarPresence";

  client.setServer(server, 1883);
  client.setCallback(callback);
  client.connect("CarPresence", willTopic, willQoS, willRetain, willMessage);
  client.subscribe(topic);
  client.subscribe(reedTopic, retained);
  Serial.print("Connecting to ");
  Serial.print(server);
  Serial.print(" as ");
  Serial.println(clientName);

  if (client.connect((char*) clientName.c_str())) {
    Serial.println("Connected to MQTT broker");
    Serial.print("Topics are: ");
    Serial.println(topic);
    Serial.println(reedTopic);

    if (client.publish(topic, "Hello from ESP8266")) {
      Serial.println("Publish ok");
    }
    else {
      Serial.println("Publish failed");
    }
  }
  else {
    Serial.println("MQTT connect failed");
    Serial.println("Will reset and try again...");
    reconnect();
  }
}

void loop() {

if (!client.connected()) {
  reconnect();
 }
 client.loop();
 httpServer.handleClient();
 client.publish(topic, "Keeping Alive");
 delay(2000);

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

Код также будет опубликован в GistHub.https://gist.github.com/hyukishi

...