[SOLVED] MQTT - publishing issue (no read state relays)

I am able to control 2 relays (Wemos D1 / mini Arduino board) from Openhab (Raspberry Pi), via MQTT. I mean to toggle ON/OFF from HABPanel.

I have these 2 items in OH2:

Switch InverterBlue1 "Blue1" { mqtt="<[brokerInverterBlue:openhab/relay1:state:MAP(onoff.map)],>[brokerInverterBlue:openhab/relay1:command:ON:ON],>[brokerInverterBlue:openhab/relay1:command:OFF:OFF]"}
Switch InverterBlue2 "Blue2" { mqtt="<[brokerInverterBlue:openhab/relay2:state:MAP(onoff.map)],>[brokerInverterBlue:openhab/relay2:command:ON:ON],>[brokerInverterBlue:openhab/relay2:command:OFF:OFF]"}

And this code/sketch in Arduino (Wemos D1 board):

/*
 * Dim - Relay Shield Toggle v1.0
 * Closes the relay for 100 ms, then opens based on OH2 event
 * Relay Shield transistor closes relay when D1 is HIGH
*/

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <Adafruit_MQTT.h>
#include <Adafruit_MQTT_Client.h>

/************************* WiFi Access Point *********************************/
#define WLAN_SSID       "xxx"
#define WLAN_PASS       "x"

/************************* MQTT Broker Setup *********************************/
#define mqtt_server      "192.168.1.2"
#define mqtt_serverport  1883                   // use 8883 for SSL
#define mqtt_username    "<mqtt_username>"
#define mqtt_password    "<mqtt_password>"

/************************* Constants, Variables, Integers, etc *********************************/
const int relayPin1 = D1;
const int relayPin2 = D2;
String relayState1 = "OFF";
String relayState2 = "OFF";
const char R1_FEED[] PROGMEM = mqtt_username "/feeds/r1"; // topic name for publishing /////////////////////////to publish
const char ONOFF_FEED[] PROGMEM = mqtt_username "/feeds/onoff";                             // string name to the feed name in order to subscribe to a topic


// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, mqtt_server, mqtt_serverport, mqtt_username, mqtt_password);

// Setup MQTT subscription 'InverterBlue' for monitoring topic for changes.
Adafruit_MQTT_Subscribe InverterBlue1= Adafruit_MQTT_Subscribe(&mqtt, "openhab/relay1");
Adafruit_MQTT_Subscribe InverterBlue2 = Adafruit_MQTT_Subscribe(&mqtt, "openhab/relay2");
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, ONOFF_FEED); /////////////////////////////////// to publish

// Create the publish object
Adafruit_MQTT_Publish r1 = Adafruit_MQTT_Publish(&mqtt, R1_FEED); ///////////////////////////////////////////// to publish


/*************************** Sketch Code ************************************/
void MQTT_connect();


void setup() {  /////////////////////////////////////////////////////////////

// Relay module prepared and set to off  
  pinMode(relayPin1, OUTPUT);
  digitalWrite(relayPin1, HIGH);
  pinMode(relayPin2, OUTPUT);
  digitalWrite(relayPin2, HIGH);

  
 //connection
  Serial.begin(115200);
  Serial.println(""); Serial.println(F("Booting... v1.0"));
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  // Connect to WiFi access point.
  Serial.print("Connecting to "); Serial.println(WLAN_SSID);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
  Serial.println("Connection Failed! Rebooting in 5 secs...");
  delay(5000);
  ESP.restart();
  }

  //////////////////////////////////////////////////////
  // Setup MQTT subscription(s) for InverterBlue feed.
  // here is one suscription for each relay
  mqtt.subscribe(&InverterBlue1); //read
  mqtt.subscribe(&InverterBlue2);//read
  mqtt.subscribe(&onoffbutton); //publish


  // how many subscriptions we want to be able to track
  #define MAXSUBSCRIPTIONS 5
  ///////////////////////////////////////////////////////

  
  // Begin OTA
  ArduinoOTA.setPort(8266); // Port defaults to 8266
  ArduinoOTA.setHostname("");   // Hostname defaults to esp8266-[ChipID]
  ArduinoOTA.setPassword((const char *)"");   // No authentication by default

  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("");
  Serial.println("Ready & WiFi connected");
  Serial.print("IP address: "); Serial.println(WiFi.localIP());

  
}



void loop() {  ///////////////////////////////////////////////////////////////////////
  ArduinoOTA.handle();
  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();
  
  // this is our 'wait for incoming subscription packets' busy subloop
  // try to spend your time here



 // START TO READ MQTT messages from OpenHab2.
 //////////////////////////////////////////////
 
  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &InverterBlue1) {Serial.print(F("InverterBlue1: ")); Serial.println((char *)InverterBlue1.lastread);}
    if (strcmp((char *)InverterBlue1.lastread, "ON") == 0) {digitalWrite(relayPin1, LOW);} 
    if (strcmp((char *)InverterBlue1.lastread, "OFF") == 0) {digitalWrite(relayPin1, HIGH);}

    if (subscription == &InverterBlue2) {Serial.print(F("InverterBlue2: ")); Serial.println((char *)InverterBlue2.lastread);}
    if (strcmp((char *)InverterBlue2.lastread, "ON") == 0) {digitalWrite(relayPin2, LOW);} 
    if (strcmp((char *)InverterBlue2.lastread, "OFF") == 0) {digitalWrite(relayPin2, HIGH);}
  }
  //////////////////////////////////////////////  
  /////end reading AND/OR publishing MQTT messages

 // Now we can publish stuff!
  Serial.print(F("\nSending r1 val "));
  Serial.print(x);
  Serial.print("...");
  if (! r1.publish(x++)) {
    Serial.println(F("Failed"));
  } else {
    Serial.println(F("OK!"));
  }

//end loop  
}

// Adjust as necessary, in seconds.  Default to 5 minutes (300 seconds).
#define MQTT_CONN_KEEPALIVE 10



  // ping the server to keep the mqtt connection alive
  // NOT required if you are publishing once every KEEPALIVE seconds
//   if(! mqtt.ping()) {
//    mqtt.disconnect();
//  }


// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }
  
  Serial.print("Connecting to MQTT... ");
  
  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
}

Where I’m stucked:
(a) not able to publish MQTT from Arduino,
(b) or/and read MQTT in Openhab).

exit status 1
'x' was not declared in this scope

This error is coming from the Arduino serial monitor, correct?
If you can control the relays via MQTT, check over all your related Openhab definitions. It’s most likely a syntax issue.

I can’t find any variable x declared. Perhaps this should be

Serial.print("x");

Yes, the variable x is not declared in your sketch
add

const int relayPin1 = D1;
const int relayPin2 = D2;
String relayState1 = "OFF";
String relayState2 = "OFF";
const char R1_FEED[] PROGMEM = mqtt_username "/feeds/r1"; // topic name for publishing /////////////////////////to publish
const char ONOFF_FEED[] PROGMEM = mqtt_username "/feeds/onoff";                             // string name to the feed name in order to subscribe to a topic
int x = 0;

Thanks, I forgot to add

int x = 0;

I’m over this step now. But still not able to “read” in Openhab (eventually I can publish MQTT from Arduino).
The sketch (from the top) will be updated with latest code.
I’m working on the errors got in Openhab log and I’ll be back.

Just make sure that the arduino published before trying to “catch” anything with OH

1 Like