Publish a specific MQTT message on startup (NodeMCU/Arduino)

Hello community.
I am just getting started with MQTT. It’s been working pretty good. I can now switch a relay connected to a NodeMCU using openhab. I will write up a documentation, once everything works as expected. For me this is a huge challenge, because programming in C (well actually programming in general) is quite new to me. So bear with me with this probably rather simple task…
Here is my Arduino Code:

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

const char* ssid = "NAME of SSID";
const char* password = "pwdforWIFI";
const char* mqtt_server = "SERVERAdress";
const int switchRelay1 = D1;

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {
   delay(100);
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) 
    {delay(500);
      Serial.print(".");
    }
  randomSeed(micros());
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length);
void setup() {
  pinMode(switchRelay1, OUTPUT); 
  digitalWrite(switchRelay1, HIGH);
  Serial.begin(115200);
  delay(100);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  delay(2000);
 }
void loop(){
 if (!client.connected() && WiFi.status() == 3) {reconnect();}
client.loop();
delay(10); 
  }
void callback(char* topic, byte* payload, unsigned int length) {
String topicStr = topic; 
  Serial.println("Callback update.");
  Serial.print("Topic: ");
  Serial.println(topicStr);
   if (topicStr == "mqtt/irrigation/relay1/switch") 
    {
     if(payload[0] == '1'){
       digitalWrite(switchRelay1, LOW);
       client.publish("mqtt/irrigation/relay1/state", "1");
       }
else if (payload[0] == '0'){
       digitalWrite(switchRelay1, HIGH);
       client.publish("mqtt/irrigation/relay1/state", "0");
       }
     }
void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    if (client.connect(clientId.c_str(), "USERMQTT", "PWDMQTT")) {
      Serial.println("MQTT connected");
        client.subscribe("mqtt/irrigation/relay1/switch");
}
else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
    }
  }

I have one problem with the state: Whenever the Modul is restarted, I want it to send the initial state (OFF on startup) so that the switches in openhab return to OFF state. Where would I put the publish message client.publish("mqtt/irrigation/relay1/state", "0") in the code? Does it belong in the void reconnect () part (the very end)? It tried yesterday and didn’t get it to work.

My approach for feedback is to read back outputs and publish them. To prevent sending publish messages for every cycle of the program I make a memory to set last state after a publish that is used in the “if” statement. This will publish the correct state of your outputs instead of the hard programmed off.

An easy fix for your question is to set a boolean to false in the declaration part, use this in the main loop as a first run to send the publish like this

bool first_run = false;

void loop() {

if (first_run == false) {
client.publish(“mqtt/irrigation/relay1/state”, “0”);
first_run = true;
}
}

Just a tip, try Easy Esp. I use this on all my nodemcu’s (sensor monitoring, relay control and mqtt reporting) . Simple Web gui configuration for everything which makes it easier to manage when you have multiple nodes.

You do not need to code this stuff yourself, unless you want to or you have found that some of the existing libraries can’t do something you want to do.

Unless you want to learn how to program ESP8266s, which can be kind of fun, you and install Tasmota or ESPEasy on the NodeMCU and configure your sensors through a web interface. I’ve used both and recommend either as excellent options.

I would put it right after the delay(2000) in setup().

If you put it in reconnect it will send the message any time the NodeMCU loses its connection the the MQTT Broker and regains that connection, meaning it has had power all that time and may not necessarily be OFF.

Vegar’s approach is probably more correct.

Or look up the last will and testament message for MQTT, it’s normally a connection published message like online that on disconnection the server posts on the clients behalf when it detects a disconnection.

Thank you guys for all the replies. I started using the Arduino environment in order to be able to program other things in the future. But I did like the approach of EspEasy, Im gonna try that this weekend.