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