Problem with MQTT - How to configure the item?

Hi, i have a problem:

I want to receive mqtt from my esp8266.

When i enter this into a linux bash, i get the following answer from the esp:

sudo mosquitto_sub -v -u mqttuser -P mqttpassword -t 'esprfid'


esprfid {"type":"access","time":1542734830,"isKnown":"true","access":"Always","username":"schwarz","uid":"12361353"}

I´m reading out rfid tags from a rfid reader.

But what do i have to enter into my openhab item?

This isn´t working:

String rfid1 "RFID Test [%s]" {mqtt="<[mosquitto:esprfid]"}

I think, the esp8266 (rfid-reader) is sending many topics and i only catch the whole string with my bash-command?

(Name of my broker is mosquitto, in my esp8266 i set up “esprfid” as topic)

EDIT:
I also tried this today, but with no luck:

String rfid1 "RFID Test [%s]" {mqtt="<[mosquitto:/esprfid/uid:string:#]"}

Are you using tasmota, easp easy, etc…firmware?

Also what part of the message are you needing/wanting?

Something in this way…

esp rfid

I want to get every part of the message, if possible. But the most important value is the UID-Number.

The UID number will need to be a Number item in OH like below:

Number rfid1 "RFID Test [%d]" {mqtt="<[mosquitto:esprfid/uid:*:default]"}

That doesn´t work. The item still stays empty.

Have you used fxmqtt or another software to see the full message?

Is this from your OH server or other? Do you have error logs pointing to an issue with mqtt?

This is from linux bash of my openhab server.

I get the following errors in openhab.log on startup:

2018-11-21 22:37:18.898 [INFO ] [t.mqtt.internal.MqttBrokerConnection] - Starting MQTT broker connection 'mqttserver'

2018-11-21 22:37:19.036 [INFO ] [t.mqtt.internal.MqttBrokerConnection] - Starting MQTT broker connection 'mosquitto'

I only use mosquitto. No idea, where i can look for the name: “mqttserver”

mqtt.cfg is only with broker mosquitto

And i also get this errors:

2018-11-21 22:37:16.949 [ERROR] [el.item.internal.GenericItemProvider] - Binding configuration of type 'mqtt' of item 'rfid1' could not be parsed correctly.

Now i tried the following, but no
luck:

Number rfid1 "RFID Test [%d]" {mqtt="<[mosquitto:esprfid/uid:*:default]"}

Number rfid1 "RFID Test [%d]" {mqtt="<[mosquitto:esprfid/uid:number:*:default]"}

Number rfid1 "RFID Test [%d]" {mqtt="<[mosquitto:esprfid/uid:command:*:default]"}

I found out why i got startet two mqtt server connections…

I looked into config/org/openhab/mqtt.config and there were two configurations inside.

I removed the wrong one, now it is only starting one connection.

When i change my item to this, i don´t get any error in the log:

Number rfid1 "RFID Test [%d]" {mqtt="<[mosquitto:esprfid/uid:command:*:default]"}

But my item still stays empty.

esprfid looks like the topic. Which is you put it into a string value shoudl return the entire json payload.

But that should return the json payload, so there’s a structure to your mqtt command you’ll need to pull the uid parameter of the json payload.

Something like

Number rfid1 "RFID Test [%d]" {mqtt="<[mosquitto:esprfid:state:JSONPATH($.uid)]"}

Thanks, that seems to work partially.

I now get a value to rfid1-number-item, but only 2 numbers “27”

My rfid-token-number is much longer…

EDIT:
There was an error in the openhab.log too, some minutes ago: But this was only a heartbeat- with no uid in the mqtt message… So how to prevent this error?

018-11-22 07:46:47.784 [WARN ] [.mqtt.internal.MqttMessageSubscriber] - Error processing MQTT message.

org.openhab.core.transform.TransformationException: Invalid path '$.uid' in '{"type":"hearthbeat","time":1542869208}'

	at org.openhab.core.transform.TransformationHelper$TransformationServiceDelegate.transform(TransformationHelper.java:67) ~[199:org.openhab.core.compat1x:2.4.0.201811151136]

	at org.openhab.binding.mqtt.internal.MqttMessageSubscriber.processMessage(MqttMessageSubscriber.java:133) [258:org.openhab.binding.mqtt:1.13.0.201811180829]

	at org.openhab.io.transport.mqtt.internal.MqttBrokerConnection.messageArrived(MqttBrokerConnection.java:570) [259:org.openhab.io.transport.mqtt:1.13.0.201811180829]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.deliverMessage(CommsCallback.java:475) [259:org.openhab.io.transport.mqtt:1.13.0.201811180829]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:379) [259:org.openhab.io.transport.mqtt:1.13.0.201811180829]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:183) [259:org.openhab.io.transport.mqtt:1.13.0.201811180829]

	at java.lang.Thread.run(Thread.java:748) [?:?]

Take your json payload to an online Json parser to get the path string properly.

I based it on one of mine and guessed your value.

1 Like

This is the whole string i get from mqtt, when i enter it into an online parser, without the leading esprfid, then i get shown exactly the same data, only every value in one line.

???

How can i read out the whole string with all values in one single item? Then i would be able to split this in a rule to get the needed values…

Can you try the folloiwng (if you haven’t already done so)?

String json {mqtt="<[mosquitto:esprfid:state:default]"}

This should give you the entire JSON “message” as a string that you could put on a sitemap (just to show that you actually get it all), write to the log, or - as you really need - parse in a rule.

1 Like

Thanks, that works! Now i get the whole mqtt-message to my string-item.

I think, i will divide my string-item with the split-command into small parts and then work with this.

Or is there a better way to do that? Maybe with json-commands? I have never used json, i only know how to split my string…

So i hope you can give me some advice, what would be the better way?

I am sure there is some Java JSON library that you can use for this, but I have never done this, so I am afraid I cannot help on this account.

My suggestion for capturing the complete JSON message in a string was only because you asked if it was possible - and as a way to verify that you actually receive the JSON message in openHAB, i.e. a debugging measure.

This is not neccessarily the way I would do this.

Given the following JSON message (from your original post):

{"type":"access","time":1542734830,"isKnown":"true","access":"Always","username":"schwarz","uid":"12361353"}

I would suggest to try to map this directly to separate items using JSONPATH (as proposed by @psyciknz above) like this:

String      rfid1_type      { mqtt="<[mosquitto:esprfid:state:JSONPATH($.type)]" }
DateTime    rfid1_time      { mqtt="<[mosquitto:esprfid:state:JSONPATH($.time)]" }
String      rfid1_isknown   { mqtt="<[mosquitto:esprfid:state:JSONPATH($.isKnown)]" }
String      rfid1_access    { mqtt="<[mosquitto:esprfid:state:JSONPATH($.access)]" }
String      rfid1_username  { mqtt="<[mosquitto:esprfid:state:JSONPATH($.username)]" }
Number      rfid1_uid       { mqtt="<[mosquitto:esprfid:state:JSONPATH($.uid)]" }

This really should work (with the disclaimer that I may have made a typo in the above). If not let’s try to find out why…

1 Like

Hi, i think i can´t use this, because the heartbeat only gives me type and time, so there is no uid in the message and there i get error messages.

So my plan is to get the whole string, then look with jsonpath-transformation if the type is access and if yes, send the uid to openhab and do some stuff.

If type is only heartbeat, then the rule will stop at this point and do nothing.

Ah… I didn’t notice that post. Sorry!

There may still be a way forward, though.

The MQTT binding supports a fifth parameter for inbound messages, called a " <regex_filter>". Using this you can make sure that only messages that matches certain criteria will be passed on to the transformation stage (JSONPATH, in your case).

Please try this:

String      rfid1_uid       { mqtt="<[mosquitto:esprfid:state:JSONPATH($.uid):.*uid.*]" }

Note! As a first attempt, I suggest you define all your items as String items just to see that you can sucessfully split your JSON message into separate parts in openHAB. If this works, then you can try to use Number and DateTime (as above) to do “automatic type conversion” if this is needed - I guess it all depends on what you will use the data for in your rules.

Hi, i tested your Json-String with Online-Parser, and got this:

  1. Wildcard

  2. uid

So this seems to work.

I’m using the [%s] Formatter in my items-setup like this:

Number    Sonoff_Pow_02_RSSI                "Stehlampe RSSI [%s]"                             <qualityofservice>      (EG_Wohnen,gRSSI)                               { mqtt="<[peter:tele/stehlampe/STATE:state:JSONPATH($.Wifi.RSSI)]" }

Have you tried it ? In a way as

as @psyciknz suggested, but changing the formatter to [%s].

Got it working, this is my rule:

rule "RFID Haustür MQTT"
	when
		Item rfid_all_haustuer received changed
	then
		val newValue_type = transform("JSONPATH", "$.type", rfid_all_haustuer.state.toString)
		if (newValue_type == "hearthbeat") {
				logInfo("RFID", "RFID Haustür -3- ---> MQTT --> only heartbeat --> " + newValue_type)
		}
		else if (newValue_type == "access") {
				val newValue_uid = transform("JSONPATH", "$.uid", rfid_all_haustuer.state.toString)
				logInfo("RFID", "RFID Haustür -4- ---> MQTT --> access : uid --> " + newValue_type + " : " + newValue_uid)
		}		
end

I have another small problem:
in time i get the epoch (ms since 1970 i think), how can i convert this into a readable format?

This gives me an error:

val newValue_time = transform("JSONPATH", "$.time", rfid_all_haustuer.state.toString)
val DateTimeType MyDateTimeTypeFromEpoch = new DateTimeType(new DateTime(newValue_time).toString)
1 Like

See this tutorial