Need help with Openhab MQTT binding with arduino shield MQTT client

Hello, I am new with openhab and i have hard time to understand how to bind Arduino Uno with ethernet shield to rasperry pi 3 running openhab. I have tried to read information about MQTT, but i have found nothing that i can get to work. If somebody could help me how to set up simple temperature sensor feedback thro MQTT to openhab, it would be great.
Now i have tried to establish information change between DHT11 temperature/humidity sensor and openhab. DHT11 sensor is connected to arduino. I believe that i have installed Mosquitto correctly, i used this instruction link to install mosquitto to rasperry pi 3.

Here are the settings that i have used on openhab:

Items:

Number Temperature “Temperature [%.1f %]” (sensors) <> {mqtt="<[broker:/arduino/ard1/TempC/state:state:default]"}

Sitemap:

sitemap default label=“openHAB User Interface” {
Frame label =“Outside Temperature” {
Text label=“Temperature” icon=“chart” {
Switch item=Chart_period label=“Time scale of trend” mappings=[0=“Hour”, 1=“Day”, 2=“Week”,3=“Month”]
Chart item=Temperature period=h refresh=300 visibility=[Chart_period==0, Chart_period==“Uninitialized”] Chart item=Temperature period=D refresh=300 visibility=[Chart_period==1]
Chart item=Temperature period=W refresh=700 visibility=[Chart_period==2]
Chart item=Temperature period=M refresh=1000 visibility=[Chart_period==3]
}

}

}

Settings:

//################################ MQTT Transport ######################################
//
// Define your MQTT broker connections here for use in the MQTT Binding or MQTT
// Persistence bundles. Replace with a id you choose.
//

// URL to the MQTT broker, e.g. tcp://localhost:1883 or ssl://localhost:8883
mqtt:broker.url=tcp://192.168.1.100:1883

rrd4j persistence:
Strategies {
default = “0 * * * * ?”
}

Items {
* : default
}

Code used in Arduino uno with ethernet shield (i know this code probably isn´t the best example but i don¨t know how to change it in order to get it work with openhab):

/*
MQTT IOT Example

  • continuously obtains values from the Virtuabotix DHT11 temperature/humidity sensor
  • formats the results as a JSON string for the IBM IOT example
  • connects to an MQTT server (either local or at the IBM IOT Cloud)
  • and publishes the JSON String to the topic named quickstart:MY_MAC_ADDRESS
    */

include <SPI.h>
include <Ethernet.h>
include <PubSubClient.h>
include <dht11.h>

// Update this to either the MAC address found on the sticker on your ethernet shield (newer shields)
// or a different random hexadecimal value (change at least the last four bytes)
byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0x00 };
char macstr[] = “deedbafefeed”;
// Note this next value is only used if you intend to test against a local MQTT server
byte localserver[] = {192, 168, 1, 100 };
// Update this value to an appropriate open IP on your local network
byte ip[] = {192, 168, 1, 80 };

char servername[]=“quickstart.messaging.internetofthings.ibmcloud.com”;
String clientName = String(“d:quickstart:arduino:”) + macstr;
String topicName = String(“iot-2/evt/status/fmt/json”);

dht11 DHT11;
float tempF = 0.0;
float tempC = 0.0;
float humidity = 0.0;
EthernetClient ethClient;

// Uncomment this next line and comment out the line after it to test against a local MQTT server
PubSubClient client(localserver, 1883, 0, ethClient);
//PubSubClient client(servername, 1883, 0, ethClient);

void setup()
{

// Start the ethernet client, open up serial port for debugging, and attach the DHT11 sensor
Ethernet.begin(mac, ip);
Serial.begin(9600);
DHT11.attach(3);

}

void loop()
{
char clientStr[34];
clientName.toCharArray(clientStr,34);
char topicStr[26];
topicName.toCharArray(topicStr,26);
getData();
if (!client.connected()) {
Serial.print("Trying to connect to: ");
Serial.println(clientStr);
client.connect(clientStr);
}
if (client.connected() ) {
String json = buildJson();
char jsonStr[200];
json.toCharArray(jsonStr,200);
boolean pubresult = client.publish(topicStr,jsonStr);
Serial.print("attempt to send ");
Serial.println(jsonStr);
Serial.print("to ");
Serial.println(topicStr);
if (pubresult)
Serial.println(“successfully sent”);
else
Serial.println(“unsuccessfully sent”);
}
delay(5000);
}

String buildJson() {
String data = “{”;
data+="\n";
data+= ““d”: {”;
data+="\n";
data+="“myName”: “Arduino DHT11”,";
data+="\n";
data+="“temperature (F)”: “;
data+=(int)tempF;
data+= “,”;
data+=”\n";
data+="“temperature ©”: “;
data+=(int)tempC;
data+= “,”;
data+=”\n";
data+="“humidity”: “;
data+=(int)humidity;
data+=”\n";
data+="}";
data+="\n";
data+="}";
return data;
}

void getData() {
int chk = DHT11.read();
switch (chk)
{
case 0:
Serial.println(“Read OK”);
humidity = (float)DHT11.humidity;
tempF = DHT11.fahrenheit();
tempC = DHT11.temperature;
break;
case -1:
Serial.println(“Checksum error”);
break;
case -2:
Serial.println(“Time out error”);
break;
default:
Serial.println(“Unknown error”);
break;
}
}

Link to instructions

When running code above i can get readings thro arduino uno serial port and i can also see that information is unsuccessfully sent to MQTT.

Here is information from MQTT:
pi@raspberrypi:~ $ mosquitto -v
1462261200: mosquitto version 1.4.8 (build date Sun, 14 Feb 2016 15:06:55 +0000) starting
1462261200: Using default config.
1462261200: Opening ipv4 listen socket on port 1883.
1462261200: Opening ipv6 listen socket on port 1883.
1462261203: New connection from 192.168.1.80 on port 1883.
1462261203: New client connected from 192.168.1.80 as d:quickstart:arduino:deedbafefeed (c1, k15).
1462261203: Sending CONNACK to d:quickstart:arduino:deedbafefeed (0, 0)
1462261224: Client d:quickstart:arduino:deedbafefeed has exceeded timeout, disconnecting.
1462261224: Socket error on client d:quickstart:arduino:deedbafefeed, disconnecting.
1462261229: New connection from 192.168.1.80 on port 1883.
1462261229: New client connected from 192.168.1.80 as d:quickstart:arduino:deedbafefeed (c1, k15).
1462261229: Sending CONNACK to d:quickstart:arduino:deedbafefeed (0, 0)

If someone could tell me what changes i need to do, it would be greatly appreciated.

Hello Newbie1,

the log from mosquitto says, that a conenction is established, but a time out occured. For this, I can’t help you any further. The only hint I can give aou is about the MQTT protocol Version. your mosquitto Broker on the pi3 uses 3.1.1 and the same protocol Version should be used by your arduino.

But: even if your connection is done, the MQTT Topic are different and must be the same.

Your Arduino publishes the Topic "iot-2/evt/status/fmt/json"
Your openHAB item subscribes to the topic “/arduino/ard1/TempC/state”

So even if your arduino publishes the correct value, the openhab item will never get this value…

First you need to check that your arduino is publishing data to mqtt. The easiest way is subscribe to your topic using another mqtt client, such as mosquitto_sub, and see what gets published.

mosquitto_sub -v -t /arduino/ard1/TempC/state 

That should print out the output from your arduino.

From what I can see of your arduino code, the topic is now set as

String topicName = String("iot-2/evt/status/fmt/json");

so you need to change that line to match what openhab is looking for.

When this works, you need to match your openhab item data to the data being produced. Your item is currently expecting just a number as the payload (the final default), but I think you are sending JSON data in the arduino code.

To use JSON data you need to use the JSON transform, so the item would be something like

Number Temperature "Temperature [%.1f %]" (sensors) <> {mqtt="<[broker:/arduino/ard1/TempC/state:state:JSONPATH($.temperature (C))]"}

I’m not sure if the parenthesis in the JSON is going to be handled by the transform, so you may want to take that out of your arduino code.

1 Like

Thanks for the quick reply, i did some changes to code based on your suggestions. Probably the JSON part of the code is useless with MQTT.

Here is the code changed (not perfect but you get the idea):

void loop()
{
getData();
if (!client.connected()) {
Serial.print(“Trying to connect to: “);
client.connect(“arduinoClient”);
}
if (client.connected() ) {
char TempC[10];
sprintf(TempC, “%f”, tempC);
boolean pubresult = client.publish(”/arduino/ard1/TempC/state”,TempC);
Serial.print("attempt to send sensor data to OpenHab ");
Serial.println();
if (pubresult)
Serial.println(“successfully sent”);
else
Serial.println(“unsuccessfully sent”);
}
delay(5000);
}

And here is information from mosquitto:

1462400461: New client connected from 192.168.1.100 as openhab (c1, k60).
1462400461: Sending CONNACK to openhab (0, 0)
1462400462: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400467: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400472: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400477: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400482: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400487: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400492: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400498: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400503: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400508: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400513: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400518: Received PUBLISH from arduinoClient (d0, q0, r0, m0, ‘/arduino/ard1/TempC/state’, … (1 bytes))
1462400521: Received PINGREQ from openhab
1462400521: Sending PINGRESP to openhab

Clearly something is happening, but not quite sure does openhab receive the information. What is the best way to see openhab log in real time?

Your includes seem to be blank in your original posting? What library are you using to do MQTT?

I’m using an arduino mega with ethernet shield to talk to OH over mqtt. (Also a Huzzah with this library for wireless sensors) I use the pubsubclient to handle MQTT. There are several decent blogs on getting started.

I used this blog a lot to get going as it also pertains to OH: https://openhardwarecoza.wordpress.com/?s=mqtt
also maybe:
http://m2mio.tumblr.com/post/30048662088/a-simple-example-arduino-mqtt-m2mio

Working code here

If you installed openhab via apt-get the command

tail -f  /var/log/openhab/events.log

will give a continuous listing of the events received by openhab. If its working you should see something like

2016-05-05 08:44:31 - Temperature_329 state updated to 17.3984

If not

tail -f /var/log/openhab/openhab.log

shows any errors that may be occurring.

It looks like you are almost there. You can publish test messages using

mosquitto_pub -t /arduino/ard1/TempC/state -m 20

rather than waiting for the arduino, which will speed up testing.

Edit:
To receive more information in openhab.log, change the DEBUG line in /etc/default/openhab to yes and restart openhab.

I believe using JSON is normal when you have more than one piece of data to send. But if you are just sending one item, it is unnecessary.

That is probably true, but i haven´t get that far yet :wink:

Now i have tried to investigate what is wrong with the code. It wont generate rrd4j persistence database to location /usr/share/openhab/etc/. So I´m assuming that openhab wont receive information from MQTT broker?
And also because Temperature is the only item that I´m using, it wont show any information from tail -f /var/log/openhab/events.log command…

Persistence is independent of mqtt. You can do this without persistence enabled at all.

No, the example I printed in my previous reply was from a temperature sensor that only sends temperature as a simple string.

If you are not getting anything in the events log, it means that ‘item’ is not receiving the data being sent. Possible reasons for this that I can think of are:

  1. Openhab is not connecting to the broker. It did in your previous log, but might not be now.
  2. The item is not configured to receive that mqtt topic. I think it was in your previous post, but has it changed?
  3. The data being sent in the message is not correct. This can be checked with using the mosquitto_sub command I mentioned earlier.

If you can’t see anything wrong, set the DEBUG line to yes in /etc/default/openhab and tail -f /var/log/openhab/openhab.log. You should get output whenever an mqtt message is sent to your topic, which will point you to what is wrong.

Hello Newbie1,

If you don’t know which part of your System doesn’t work, maybe it’s useful to split things up.

To check if your Mosquitto server is running and working on your Pi3, then it is possible to install the “MQTT Dashboard” on an Android phone or tablet. With this piece of software you can subscribe and publish messages from/to your Server. In conjunction with the mosquitto_pub command Graham told you, you can have a running MQTT System without openhab being involved. (Good for testing purpose)

When this part is working you know that your broker can receive Messages or publish Messages.

The next steps will be your openhab items. please remember that it is a difference if you have a leading slash “/” at the beginning for your Topics.
/arduino/ard1/TempC/state
is a different Topic than
arduino/ard1/TempC/state