Hello everyone!
I have openhab installed on rasPi3. rasPi is connected to LAN via wifi on static 192.168.5.16. I have NodeMCU 1.0 on the same LAN with static 192.168.5.17 address. I have mqtt up and running. NodeMCU is subscribed to espIn, where it waits for ‘0’ (on), ‘1’ (off) or ‘2’ (switch state). When it changes state of the LED it sends ‘0’ (on) or ‘1’ (off) to the espOut topic.
When I connect to rasPi via SSH, I can control the led with
mosquitto_pub -t espIn -m "1" (or 0, or 2)
and it works just fine. I have subscribed to espOut,
mosquitto_sub -t espIn -t espOut
just to check if it sends correct state, and it also works just fine.
Now, let’s go to the openhab settings.
In openhab.cfg I have following settings for mqtt:
mqtt:lovronix.url=tcp://192.168.5.16:1883
mqtt:lovronix.clientId=lovro
lovros.items looks like:
Group All
Group gGroundFloor (All)
Group GF_Living "Living Room" <video> (gGroundFloor)
Switch led "Relej 1" (gGroundFloor) {mqtt="<[lovronix:espOut:state:default]" }
and lovros.sitemap looks like:
sitemap lovros label="MQTT"
{
Frame label="NodeMCU MQTT upravljanje LEDicom" {
Switch item=led {mqtt=">[lovronix:espIn:command:ON:0],>[lovronix:espIn:command:OFF:1]"}
}
}
And it’s not working at all. I have read a lot of tutorials and various similar topics, but I don’t know what is going on here. I belive that it is something small, but I can’t see it.
Here is the .ino code for NodeMCU, just in case…
/*
It connects to an MQTT server then:
- on 0 switches off relay
- on 1 switches on relay
- on 2 switches the state of the relay
- sends 0 on off relay
- sends 1 on on relay
It will reconnect to the server if the connection is lost using a blocking
reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
achieve the same result without blocking the main loop.
The current state is stored in EEPROM and restored on bootup
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Bounce2.h>
#include <EEPROM.h>
const char* ssid = "mySSID";
const char* password = "myPASS";
const char* mqtt_server = "192.168.5.16";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
const char* outTopic = "espOut";
const char* inTopic = "espIn";
int relay_pin = 2;
int button_pin = 0;
bool relayState = LOW;
// Instantiate a Bounce object :
Bounce debouncer = Bounce();
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
extButton();
for (int i = 0; i<500; i++) {
extButton();
delay(1);
}
Serial.print(".");
}
digitalWrite(13, LOW);
delay(500);
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);
digitalWrite(13, HIGH);
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '0') {
digitalWrite(relay_pin, LOW); // Turn the LED on (Note that LOW is the voltage level
Serial.println("relay_pin -> LOW");
relayState = LOW;
client.publish(outTopic, "0");
EEPROM.write(0, relayState); // Write state to EEPROM
EEPROM.commit();
}
else if ((char)payload[0] == '1') {
digitalWrite(relay_pin, HIGH); // Turn the LED off by making the voltage HIGH
Serial.println("relay_pin -> HIGH");
relayState = HIGH;
client.publish(outTopic, "1");
EEPROM.write(0, relayState); // Write state to EEPROM
EEPROM.commit();
}
else if ((char)payload[0] == '2') {
relayState = !relayState;
digitalWrite(relay_pin, relayState); // Turn the LED off by making the voltage HIGH
Serial.print("relay_pin -> switched to ");
Serial.println(relayState);
if (relayState == 1) {
client.publish(outTopic, "1");
}
else if (relayState == 0) {
client.publish(outTopic, "0");}
EEPROM.write(0, relayState); // Write state to EEPROM
EEPROM.commit();
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(outTopic, "Sonoff1 booted");
// ... and resubscribe
client.subscribe(inTopic);
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
for (int i = 0; i<5000; i++) {
extButton();
delay(1);
}
}
}
}
void extButton() {
debouncer.update();
// Call code if Bounce fell (transition from HIGH to LOW) :
if (debouncer.fell()) {
Serial.println("Debouncer fell");
// Toggle relay state :
relayState = !relayState;
digitalWrite(relay_pin, relayState);
EEPROM.write(0, relayState); // Write state to EEPROM
if (relayState == 1) {
client.publish(outTopic, "1");
}
else if (relayState == 0) {
client.publish(outTopic, "0");
}
}
}
void setup() {
EEPROM.begin(512); // Begin eeprom to store on/off state
pinMode(relay_pin, OUTPUT); // Initialize the relay pin as an output
pinMode(button_pin, INPUT); // Initialize the relay pin as an output
pinMode(13, OUTPUT);
relayState = EEPROM.read(0);
digitalWrite(relay_pin, relayState);
debouncer.attach(button_pin); // Use the bounce2 library to debounce the built in button
debouncer.interval(50); // Input must be low for 50 ms
digitalWrite(13, LOW); // Blink to indicate setup
delay(500);
digitalWrite(13, HIGH);
delay(500);
Serial.begin(115200);
setup_wifi(); // Connect to wifi
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
extButton();
}
I have tried controling LED with HTTP request, and it works nice. I also have a USB webcam in the rasPi, and it sends a picture every minute on my second openhab sitemap, without a problem. Now I’m stuck with mqtt. I want to control relays and to read sensors, and mqtt looks to me like a perfect solution. But I just can’t make it running from the my.openhab.org sitemap.
Thank you in advance
Lovro