Thing with channels on same MQTT topic with different data

Hi all,

I’ve got an esp32 that is sending out to my mqtt host,
it always sends over the following topic:
tele/SerreScanner/SENSOR

but it sends data for multiple ‘sensors’:
examples:
For the esp:

{“Time”:“2021-05-06T12:09:32”,“ESP32”:{“Temperature”:53.9},“TempUnit”:“C”}

for a plant sensor:
{“Time”:“2021-05-06T12:09:21”,“Flora6caa96”:{“mac”:“c47c8d6caa96”,“Temperature”:22.2,“Illuminance”:1092,“Moisture”:33,“Fertility”:226,“Battery”:null,“RSSI”:-82}}

My goal:
Determine the thing by the value after time,
and in my thing use the other values as channels

does anyone have a clue how this can be done?

Filter for a keyword using REGEX. If present, extract value with JSONPATH.

this probably can’t be done completly in gui?

What makes you think that? It’s just form filling instead of typing parameters in a xxx.things file.

I’ve installed the regex and jsonpath now,
could you give me another push regarding the two examples I gave above?

Not really. Let’s say you want plant sensor thingy ‘Moisture’.
Use a REGEX to filter for text “Flora6caa96”, then chain to a JSONPATH for “Moisture” value.
This will ignore the “ESP32” messages.

It’s up to you to find the filter keywords -“Temperature” for example will not do.

Thanks to some fine help I received yesterday and the day before I can positively say this is not a problem.

  1. Create the MQTT thing to connect to the broker. Do not configure channels on it.
  2. Create a new ‘thing’ for each device (Just one?)
  3. For each sensor on the ‘device’ thing you created, configure a channel.
  4. In the channel configure the MQTT State Topic (‘tele/SerreScanner/SENSOR’ in your case) and under the advanced section add an input transform as a REGEX. e.g.

Note that OH REGEX’s are ‘unique’ in that you have to match the WHOLE input line (i.e. prefix and postfix with .*). You an see from the transport I use that it matches a MAC address… Which is the identifier for each sensor I have on my 1 mqtt topic. (I actually have two REGEX’s for each sensor. Temp and Humid so you can pull multiple data from each entry just by configuring a separate channel) - I did wonder if you can pull two items per channel, but haven’t investigated how I’d do that yet and 2x channels works anyway.

  1. Add an item to the channel. Make sure you select ‘default’ for the items profile or the item won’t get the read value set.

Channel will then look like this

Check the event logs to make sure it’s updating…I found OH’s REGEX’s a PITA to debug TBH so don’t try to change too much at once. Get one thing working and go from there.

1 Like

so If i read your post correct,
you are not using jsonpath,

If i indeed want to make a thing for every ‘thing’ that sends info to my ‘collector’ which broadcasts it over mqtt it’s enough to filter on the name on every channel i add too.

I’m absolutly no hero in the regex department :smiley: i just hope it wont be to complex given al the brackets and stuff on my plant sensors. always welcome to chip in :smiley:

That’s right. No jsonpath. My data isn’t json for a start… It’s literally just text like this

4126 cc50e381b620 : humid 55.56 temp 12.66 press 1001.73
-1084477346 000336da : humid 53.40 temp 17.20 heat_ind 16.36
3376294 cc50e381bf8c : humid 56.50 temp 12.80 heat_ind 11.61
446035 3c71bfa94cc0 : humid    83.70 temp    12.21 press  1000.55
-1054281387 000336da : humid 53.30 temp 17.10 heat_ind 16.25

Where the second field is essentially the ID of the sensor…

If you’re using pure JSON, then yes you’re probably better off using jsonpath, just replace the REGEX with the jsonpath equivalent I believe

if the keyword is ESP32, and I want To return it’s temperature,
shouldn’t

> REGEX: (.*ESP32.*)∩JSONPATH:$.Temperature

do that?

Temperature is nested, so maybe
REGEX:(.*ESP32.*)∩JSONPATH:$.ESP32.Temperature

thx for the reply,
i’ve tried that one but keeps returning NULL

I’ve never understood why people use MQTT like this (it’s not you, it’s who ever implemented the firmware). One of the guiding principles of MQTT is that you should not impose a processing burden on your subscribers. Sending such diverse messages that need to be processed just to figure out whether or not you care about the message is imposing pretty heavily on the subscribers. At a minimum each sensor should have its own topic. Even better would be to skip the JSON and publish each piece of data on its own topic.

Anyway, assuming you can’t fix this at the source, the overall pattern for a REGEX filter is as follows:

REGEX:(.*unique string.*)∩JSONPATH:$.field

where “unique string” is the unique sequence of characters that identifies this as a message the Channel cares about and $.field is the JSONPATH to the JSON field to extract. Pay close attention to the nesting in the JSON.

Given the examples above you would use something like

REGEX:(.*ESP32.*)∩JSONPATH:$.ESP32.Temperature

to extract the sensor value for the ESP32.

You would use something like

REGEX(.*Flora6caa96.*)∩JSONPATH:$.Flora6caa96.Temperature

to extract the temperature from that specific Flora device.

When things don’t work, break it down. Create a String Channel and set it up with the REGEX filter. Does it only capture the messages that match? Once you have that working then try adding the JSONPATH transform. But do it little by little.

2 Likes

Thx lots, seems i made a typo on rossko57’s last post,
he posted the answer to.

you expression seems to do what i wanted it to do,

but i must say I agree on the mqtt thing it would have been easier for everyone if they just lengthened the topic, even just doing tele/SerreScanner/SENSOR/flora1 and tele/SerreScanner/SENSOR/esp32

would make it so much easier, and more inline with the whole topic logic,
anyways thanks alot all for the help :slight_smile: