Подключение нескольких топиков - MQTT

Я настраиваю ESP8266 с помощью Arduino Uno.

У меня есть несколько тем MQTT, на которые я хочу подписаться, и я не хочу повторять код 3 или 4 раза (в Python я бы создал список - и сделал цикл for, чтобы подписаться на все)

Вот мои темы:

//MQTT topic
const char* deviceName = "Sonoff1";
const char* deviceTopic = "HomePi/Switches/Sonoff1";
const char* msgTopic = "HomePi/Messages";
const char* groupTopic = "HomePi/All";

Это функция, регистрирующая одну тему:

void reconnect() {
        // Цикл до тех пор, пока мы не будем повторно подключены
        while (!client.connected()) {
                Serial.print("Attempting MQTT connection...");
                // Попытка подключения
                if (client.connect(deviceName,user, passw)) {
                        Serial.println("connected");
                        pub_msg("Power On");
                        client.subscribe(deviceTopic);
                } else {
                        Serial.print("failed, rc=");
                        Serial.print(client.state());
                        Serial.println(" try again in 5 seconds");
                        // Подождите 5 секунд, прежде чем повторить попытку
                        delay(5000);
                }
        }
}

Ценю вашу любезную помощь,

Парень

, 👍0

Обсуждение

создайте массив и используйте цикл for, @Juraj


2 ответа


Лучший ответ:

1

просто для завершения:

добавлен массив (спасибо Юраю):const char* topicsArry[]={deviceTopic, msgTopic, groupTopic, "HomePi/Dvir/Clock", "HomePi/Dvir/Alerts"};

цикл for поверх этого цикла и использование sizeof ( что для меня не было тривиальным) привели к :

void reconnect() {
        // Цикл до тех пор, пока мы не будем повторно подключены
        while (!client.connected()) {
                Serial.print("Attempting MQTT connection...");
                // Попытка подключения
                if (client.connect(deviceName,user, passw)) {
                        Serial.println("connected");
                        pub_msg("Power On");
                        for (int i=0; i<=sizeof(topicsArry)/sizeof(char *); i++){
                          client.subscribe(topicsArry[i]);
                          char msg[50];
                          sprintf(msg, "Subscribed to %s",topicsArry[i]);
                          pub_msg(msg);
                        }
                } else {
                        Serial.print("failed, rc=");
                        Serial.print(client.state());
                        Serial.println(" try again in 5 seconds");
                        // Подождите 5 секунд, прежде чем повторить попытку
                        delay(5000);
                }
        }
}
,

5

Вы можете облегчить себе жизнь, если расположите названия тем иерархически. В качестве примера предположим, что у нас есть мультимедийный контроллер, который принимает различные команды обмена:

  • медиасервер /набор / громкость
  • медиасервер / установить / приостановить
  • медиасервер/набор/аудио/источник
  • медиасервер /набор /видео/субтитры
  • и т.д....

Затем вы можете подписаться на "mediaserver/set/#".

Для зацикливания на массиве тем вы можете воспользоваться преимуществами цикла for на основе диапазона современного C ++:

  • https://en.cppreference.com/w/cpp/language/range-for

Пример кода:

const char *topicArry[] = {
    deviceTopic, msgTopic, groupTopic,
    "HomePi/Dvir/Clock", "HomePi/Dvir/Alerts"
};
void reconnect() {
    // Цикл до тех пор, пока мы не подключимся снова
    while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        // Попытка подключения
        if (client.connect(deviceName,user, passw)) {
            Serial.println("connected");
            pub_msg("Power On");
            for (const char *topic : topicsArry) {
                client.subscribe(topic);
                char msg[50];
                sprintf(msg, "Subscribed to %s",topic);
                pub_msg(msg);
            }
        } else {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            // Подождите 5 секунд, прежде чем повторить попытку
            delay(5000);
        }
    }
}
,