[OH2] Control ESP8266 Relay using MQTT Eventbus

correct !
Good luck ! :slight_smile:

Note: The example ESP code does not care what payload (ON/OFF/Blah-Blah/etc) arrives to it’s subscribed topic (mqtt/back-topic)

It just reacts to an incoming message (of any payload content)
Make sure that you are subscribed to the correct topic in the code:

Adafruit_MQTT_Subscribe InverterBlue = Adafruit_MQTT_Subscribe(&mqtt, "openhab/out/brokerInverterBlue");

Dim, I succesfully replicated your example fully.
But now I’m stucked trying to adapt your sketch for Arduino in order to:

  1. control / toggle ON/OFF the relays (2 relays)
  2. see each relay state in HABPanel.

I have working solution for:
broker = brokerInverterBlue
topic = relays

There are the defined items:

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

Could you enlight me, please? How to adapt your code to my needs?
Or point me in the right direction…

/*
 * 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       "Chiar vrei internet?"
#define WLAN_PASS       "chiarvreau"

/************************* 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";

int value = 0;
int relayState = LOW;

// 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 subscription 'InverterBlue' for monitoring topic for changes.
Adafruit_MQTT_Subscribe InverterBlue = Adafruit_MQTT_Subscribe(&mqtt, "openhab/relays");

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

void setup() {
  Serial.begin(115200);
  Serial.println(""); Serial.println(F("Booting... v1.0"));
  pinMode(relayPin, 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 for InverterBlue feed.
  mqtt.subscribe(&InverterBlue);

  // Begin OTA
  ArduinoOTA.setPort(8266); // Port defaults to 8266
  ArduinoOTA.setHostname("InverterBlue");   // Hostname defaults to esp8266-[ChipID]
  ArduinoOTA.setPassword((const char *)"<pass>");   // 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



/*//----------------------------------------------------------- */

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &InverterBlue) {
      Serial.print(F("Got: ")); Serial.println((char *)InverterBlue.lastread);
      // close the relay for 100 ms
      Serial.println("Close Relay for 100 ms & then Open");
      digitalWrite(relayPin, HIGH);
      delay(togDelay);
      digitalWrite(relayPin, LOW);
      delay(postDelay);
    }
  }
/*//----------------------------------------------------------- */

  // 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!");
}

It’s not my code… I got it from someone else (I don’t even remember who gave it to me :))

I can’t help much with Arduino Code… my skills are a bit rusty :slight_smile:

I would google other forums for similar examples and adapt it to my needs.

Thanks for quick reply. :slight_smile:
I’ll try hard.

I followed the tutorial, thanks in advance for making it.
I have the problem with esp that does not receive the subscription, I think.
From the serial I see MQTT connected!
from MQTTlens I created a subscription: openhab / out / Robo500 / command
by pressing the GO button! receives two messages at a time but the esp does not activate the relay
from OH event.log I see that the robo500 item receives the ON command
the mqtt.eventbus.cfg file has no configuration

this on the esp:

Adafruit_MQTT_Subscribe Robo500 = Adafruit_MQTT_Subscribe(&mqtt, "openhab/out/Robo500/command");

this on the items:

Switch  Robo500  "Robo 500"   <siren>    {mqtt=">[mosquitto:openhab/out/Robo500/command:command:ON:default]", autoupdate="false"}

my mosquitto.clientId = mosquitto

what could be the problem?
thank you
Davide

I found the problem, it was missing in the setup:

mqtt.subscribe (& Robo500);

but it keeps sending two messages at a time …

OH2 is sending 2 mqtt messages every time you press the Robo500 button on your sitemap?

Most likely, you followed the tutorial on the first post, setup your MQTT-Event Bus config in a previous step and later on, you commented out the stuff in /etc/openhab2/services/mqtt-eventbus.cfg.

This does not make the parameters go away from their storage destination = /var/lib/openhab2/config/org/openhab/mqtt-eventbus.config (there is an issue with stale configs).

To make them go away, you should not comment them out but set them to nothing, or use the config pid: story as the first line in your *.cfg

This means that the Item will trigger one MQTT message from the “focused” binding config and another MQTT message will be initiated from the EventBus integration = resulting in 2 messages (@rlkoshak it seems that this works as expected :slight_smile:)

Can you check and post the contents of /var/lib/openhab2/config/org/openhab/mqtt-eventbus.config ?

If there is something there: stop OH2, delete this file, start OH2.

99,9% this is the problem… but you never know… so post also your sitemap config plz just to check it

1 Like

mqtt-eventbus.cfg

# Name of the broker as it is defined in the openhab.cfg. If this property is not available, no event bus MQTT binding will be created.
broker=mosquitto

# When available, all status updates which occur on the openHAB event bus are published to the provided topic. The message content will 
# be the status. The variable ${item} will be replaced during publishing with the item name for which the state was received.
#statePublishTopic=openhab/out/${item}/state 

# When available, all commands which occur on the openHAB event bus are published to the provided topic. The message content will be the 
# command. The variable ${item} will be replaced during publishing with the item name for which the command was received.
#commandPublishTopic=openhab/out/${item}/command

# When available, all status updates received on this topic will be posted to the openHAB event bus. The message content is assumed to be 
# a string representation of the status. The topic should include the variable ${item} to indicate which part of the topic contains the 
# item name which can be used for posting the received value to the event bus.
#stateSubscribeTopic=openhab/in/${item}/state

# When available, all commands received on this topic will be posted to the openHAB event bus. The message content is assumed to be a 
# string representation of the command. The topic should include the variable ${item} to indicate which part of the topic contains the 
# item name which can be used for posting the received value to the event bus.
#commandSubscribeTopic=openhab/in/${item}/command

I am interested on his evil brother, the mqtt-eventbus.config

this?

broker="mosquitto"
commandPublishTopic="openhab/out/${item}/command"
commandSubscribeTopic="openhab/in/${item}/command"
service.pid="org.openhab.mqtt-eventbus"
statePublishTopic="openhab/out/${item}/state"
stateSubscribeTopic="openhab/in/${item}/state"

there you go

the evil brother (/var/lib/openhab2/config/org/openhab/mqtt-eventbus.config) has gone astray and is sending a second mqtt message (via the EventBus integration which is still active) every time you press that Robo500 button, parallel to the first message that is originating due to the Item config (via the MQTT Binding).

Put the evil brother back in his place by: deleting him :stuck_out_tongue: (effectively, disabling the MQTT-EventBus integration)

1 Like

perfect! now it works properly, thank you!
A question, if I can approfttare, I have second problem, from the serial monitor I see that every now and then reconnects to the MQTT broker
“Connecting to MQTT … MQTT Connected!”
this causes a new subscription and the relay snaps, did you have the same problem?

No… mine is stable with: 51 days uptime and no re-connections (screenshot from my Unifi controller software)

Maybe your WLAN signal is not strong enough? You could post your code on a new thread to be checked but there is no guarantees for troubleshooting since this is mainly an openHAB forum (not ESP code focused :slight_smile:)

ok, first I try on an arduino forum
if I then find the solution here, maybe it helps others

1 Like

solved.
Reading the definitions of the library, I read that the connection must always remain active by sending subscriptions, if this does not happen, the function in the sketch makes a new connection.
Then inserting:

if (! mqtt.ping ()) {
     mqtt.disconnect ();
   }

the connection remains alive.

Question
how do I send a publication on the ON OFF status to OH?
for the item I wrote this:

Robo 500 "Robo 500" switch <siren> {mqtt = "<[mosquitto: openhab / in / Robo500 / state: state: MAP (onoff.map)],> [mosquitto: openhab / out / Robo500 / command: command: ON : ON],> [mosquitto: openhab / out / Robo500 / command: command: OFF: OFF] ", autoupdate =" false "}

in the sketch:

Adafruit_MQTT_Publish feed = Adafruit_MQTT_Publish (& mqtt, "openhab / in / Robo500 / state");

loop:

  if (digitalRead (D4) == HIGH) {
    feed.publish ("ON");
  }
   if (digitalRead (D4) == LOW) {
    feed.publish ("OFF");
  }

I need to manage a pulse relay, controlled by a button or OH

Almost correct :slight_smile: (I made some changes… also make sure that you don’t have unnecessary spaces in your Item config and your topic in the sketch)

Switch Robo500 "Robo 500" switch <siren> { mqtt=">[mosquitto:openhab/out/Robo500/command:command:*:default], <[mosquitto:openhab/in/Robo500/state:state:MAP(onoff.map)]" }

OH gives me this error:
[ERROR] [.mqtt.internal.MqttMessageSubscriber] - Error processing MQTT message.
MQTTLENS show correct message on topic: “openhab / in / Robo500 / state”
I do not understand if the error depends on OH or the sketch

what is the message payload published on topic openhab/in/Robo500/state ?
and what does the onoff.map contain?

Anyway: For troubleshooting stuff, it’s better to open up a new thread and link to the original tutorial thread.

if (digitalRead (FEED) == HIGH) {
feed.publish (“ON”);
}
if (digitalRead (FEED) == LOW) {
feed.publish (“OFF”);
}

I keep getting this message " Got: ON
Close Relay for 100 ms & then Open

And what should i add to the code to make the gate close ?