[OH2] Control ESP8266 Relay using MQTT Eventbus

You could try to add some code in the last section (messageReceived)
In my example, I monitor the topic from the ESP side but I don’t publish anything to the Broker from the ESP
In your example, the reverse is true

So: You want an ESP code that does both (publishes the state as well as subscribes to a topic) basically… correct?

Hi @Dim

Correct.
My thought was to have a reed switch connected to pin D7 and GND using the internal pullup to send a MQTT stating the door is open. And have a relay connected to D1 that would allow me to close it when a software switch is pressed in the OH2 UI. I believe that requires the ESP code to both publish and subscribe but I’m open to any suggestions.

1 Like

Great tutorial. Already using this for my home made rollershutters. Thanks!

1 Like

Matt Kaczynski is the best what he do. Can’t wait for more videos

hello im quite new to rpi3 and open hap2

i was following this tutorial
i made connection between mqqt and nodemcu trigger relay via mqqt.fx
but im un able to toggle out via rpi paper ui

I have the same error as you, jdeka1…
Using Wemos D1 R2 (Arduino) board, RPi and OH2.3. Tried to test connection also with MQTT.fx bellow.
But I’m getting error trying to connect Arduino to OH2.3.

Connecting to MQTT... Connection failed
Retrying MQTT connection in 5 seconds...

Checked also RPi with ‘sudo systemctl status mosquitto’ and there is Active.


● mosquitto.service - LSB: mosquitto MQTT v3.1 message broker
   Loaded: loaded (/etc/init.d/mosquitto; generated; vendor preset: enabled)
   Active: active (running) since Sat 2018-07-14 21:36:06 EEST; 15h ago
     Docs: man:systemd-sysv-generator(8)
  Process: 272 ExecStart=/etc/init.d/mosquitto start (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/mosquitto.service
           └─332 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Jul 14 21:36:04 openHABianPi systemd[1]: Starting LSB: mosquitto MQTT v3.1 message broker...
Jul 14 21:36:06 openHABianPi mosquitto[272]: Starting network daemon:: mosquitto.
Jul 14 21:36:06 openHABianPi systemd[1]: Started LSB: mosquitto MQTT v3.1 message broker.

This is mttq.cfg:

MQTT.url=tcp://192.168.1.2:1883
MQTT.clientId=
MQTT.user=
MQTT.pwd=

This is the error result from MQTT.fx:

2018-07-15 13:57:22,793  INFO --- MqttFX ClientModel             : MqttClient with ID MQTT_FX_Client assigned.
2018-07-15 13:57:24,813 ERROR --- MqttFX ClientModel             : Error when connecting
org.eclipse.paho.client.mqttv3.MqttException: Unable to connect to server
	at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:94) ~[org.eclipse.paho.client.mqttv3-1.2.0.jar:?]
	at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:701) ~[org.eclipse.paho.client.mqttv3-1.2.0.jar:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_162]
	at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_162]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source) ~[?:1.8.0_162]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[?:1.8.0_162]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.8.0_162]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.8.0_162]
	at java.lang.Thread.run(Unknown Source) [?:1.8.0_162]
Caused by: java.net.ConnectException: Connection refused: connect
	at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[?:1.8.0_162]
	at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) ~[?:1.8.0_162]
	at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) ~[?:1.8.0_162]
	at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) ~[?:1.8.0_162]
	at java.net.AbstractPlainSocketImpl.connect(Unknown Source) ~[?:1.8.0_162]
	at java.net.PlainSocketImpl.connect(Unknown Source) ~[?:1.8.0_162]
	at java.net.SocksSocketImpl.connect(Unknown Source) ~[?:1.8.0_162]
	at java.net.Socket.connect(Unknown Source) ~[?:1.8.0_162]
	at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:84) ~[org.eclipse.paho.client.mqttv3-1.2.0.jar:?]
	... 8 more
2018-07-15 13:57:24,815 ERROR --- MqttFX ClientModel             : Please verify your Settings (e.g. Broker Address, Broker Port & Client ID) and the user credentials!
org.eclipse.paho.client.mqttv3.MqttException: Unable to connect to server
	at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:94) ~[org.eclipse.paho.client.mqttv3-1.2.0.jar:?]
	at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:701) ~[org.eclipse.paho.client.mqttv3-1.2.0.jar:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_162]
	at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_162]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source) ~[?:1.8.0_162]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[?:1.8.0_162]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.8.0_162]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.8.0_162]
	at java.lang.Thread.run(Unknown Source) [?:1.8.0_162]
Caused by: java.net.ConnectException: Connection refused: connect
	at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[?:1.8.0_162]
	at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) ~[?:1.8.0_162]
	at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) ~[?:1.8.0_162]
	at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) ~[?:1.8.0_162]
	at java.net.AbstractPlainSocketImpl.connect(Unknown Source) ~[?:1.8.0_162]
	at java.net.PlainSocketImpl.connect(Unknown Source) ~[?:1.8.0_162]
	at java.net.SocksSocketImpl.connect(Unknown Source) ~[?:1.8.0_162]
	at java.net.Socket.connect(Unknown Source) ~[?:1.8.0_162]
	at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:84) ~[org.eclipse.paho.client.mqttv3-1.2.0.jar:?]
	... 8 more
2018-07-15 13:57:24,834  INFO --- ScriptsController              : Clear console.
2018-07-15 13:57:24,834 ERROR --- BrokerConnectService           : Unable to connect to server

At file mqtt-eventbus.cfg I tried with and without these:

broker=MQTT
statePublishTopic=openhab/out/$.{item}/state
commandPublishTopic=openhab/out/${item}/command
stateSubscribeTopic=openhab/in/${item}/state
commandSubscribeTopic=openhab/in/${item}/command

OH2 tells me that there a broker is started:

2018-07-15 22:12:33.471 [INFO ] [t.mqtt.internal.MqttBrokerConnection] - Starting MQTT broker connection 'broker'

Do you have any ideea what to try further?
Thanks.

I managed to connected.

post the contents of your /etc/mosquitto/mosquitto.conf plz
something is wrong with your Broker (maybe?)

Dim, I’ve managed to connected Arduino (D1) to MQTT now. But I’m trying to figure out how I can control the relays from Habpanel.

1 Like

You need to define an Item in your OH2 system that is bound to the proper MQTT topic
Then, use this new Item in your HABPanel layout.

edit: I recommend that you don’t use the MQTT - EventBus integration but setup a focused MQTT bound Item
(unless you need all of the integration features)

I’ve already define it:

Switch InverterBlue "Testing..." { mqtt="<[brokerInverterBlue:mqtt/topic:state:ON], >[brokerInverterBlue:mqtt/back-topic:command:*:OFF]" }  

I’ve created also a button in Habpanel with ON/OFF .
I can see the action of this button in OH2 log:

2018-07-16 13:42:42.496 [ome.event.ItemCommandEvent] - Item 'InverterBlue' received command ON

2018-07-16 13:42:42.503 [vent.ItemStateChangedEvent] - InverterBlue changed from OFF to ON

2018-07-16 13:42:45.082 [ome.event.ItemCommandEvent] - Item 'InverterBlue' received command OFF

2018-07-16 13:42:45.096 [vent.ItemStateChangedEvent] - InverterBlue changed from ON to OFF

I’ve update Arduino sketch to connect with this broker:

/*
 * 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    ""
#define mqtt_password    ""

/************************* Constants, Variables, Integers, etc *********************************/
const int relayPin = D1;
const long togDelay = 100;  // pause for 100 milliseconds before toggling to Open
const long postDelay = 200;  // pause for 200 milliseconds after toggling to Open
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 'Robo500' for monitoring topic for changes.
Adafruit_MQTT_Subscribe InverterBlue = Adafruit_MQTT_Subscribe(&mqtt, "openhab/out/brokerInverterBlue");

/*************************** 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 Robo500 feed.
  mqtt.subscribe(&InverterBlue);

  // Begin OTA
  ArduinoOTA.setPort(8266); // Port defaults to 8266
  ArduinoOTA.setHostname("InverterBlueChipID");   // 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!");
}

The serial from Arduino tells me that MQTT connected.

Ready & WiFi connected
IP address: 192.168.1.102
Connecting to MQTT... MQTT Connected!

mqtt-eventbus file has been modified:

broker=brokerInverterBlue
statePublishTopic=openhab/out/${item}/state
commandPublishTopic=openhab/out/${item}/command
stateSubscribeTopic=openhab/in/${item}/state
commandSubscribeTopic=openhab/in/${item}/command

But I cannot see any action in Arduino when I clicked the button in OH2. What’s wrong?

First of all, verify that the Broker is receiving the message from OH2.
Use MQTT.fx to see if the payload arrives to the topic you are publishing

Secondly:

  1. Remove all settings from mqtt-eventbus.cfg. You don’t need this if you use an MQTT Bound item
  2. Use the same MQTT Broker alias in your Item config as in your mqtt.cfg file (MQTT vs brokerInverterBlue)
Switch InverterBlue "Testing..." { mqtt="<[MQTT:mqtt/topic:state:ON], >[MQTT:mqtt/back-topic:command:*:OFF]" }  

mqtt.cfg has this:

brokerInverterBlue.url=tcp://192.168.2:1883

I have this broker only.

Tested now with MQTT.fx… I cannot see any message from the Habpanel’s button (ON/OFF).

Ok, you updated it (in post #25 you have another mqtt.cfg listed)

If the Borker is on the same host, use localhost IP:

brokerInverterBlue.url=tcp://127.0.0.1:1883

something is wrong with your Item definition.

double check the syntax with https://www.openhab.org/addons/bindings/mqtt1/

Try:

Switch InverterBlue "Testing..." { mqtt="<[brokerInverterBlue:mqtt/topic:state:default], >[brokerInverterBlue:mqtt/back-topic:command:*:default]" }  

Changed to localhost. In MQTT.fx, under Topics Collector I start to see:
mqtt/back-topic

But still nothing else in MQTT.fx, under Subscribe messages window.

I tried to change the item code but now I’m getting this error in log:

org.eclipse.smarthome.model.item.BindingConfigParseException: Configuration 'brokerInverterBlue::mqtt/back-topic:command:*:default' is not a valid outbound configuration: Configuration requires 5 parameters separated by ':'

I made a typo and I corrected the post above (it had 2 colons :: after the broker alias)
take the new version of the Item config :slight_smile:

Update the item as you instructed. No more error in log.
But, in MQTT.fx I can see this Topics Collector only:

mqtt/back-topic

I think I need to see also: topic (not only back-topic, right?).

Well… if something (i.e. your ESP code) is publishing to that topic… then yes.
openHAB subscribes to that topic (mqtt/topic) and gets the state updates.
openHAB publishes the commands that you issue (from toggling ON/OFF the Switch from HABPanel) to the mqtt/back-topic

Note: In my example from the first post, I don’t publish the state from the ESP code.