In the MQTT1 binding there was a feature that let us filter messages published to a given topic and only pass those that match a given REGEX to the transformation and/or on to the Item. This was useful to handle devices that publish messages to a single well known topic for all their devices.
For example, the official firmware from the vendor of Shelly devices have a request/response protocol over MQTT to get meta data about the devices (IP address, MAC address, firmware version, whether there is a firmware update, etc.). Each individual device has their own topic you can send “announce” to. In response, the device will publish a JSON message to
OK, well we have to deal with it if we don’t want to have to install alternative firmware.
Each Shelly device has a unique name. For example shelly1-25A289. The JSON published to
shellies/announcement includes this unique name.
The MQTT2 binding lacks direct support for a REGEX filter as a separate parameter. But it does support chaining transformations on incoming messages. So we can chain a REGEX transformation that matches and returns the entire message but only if it contains the unique name. Next we chain that to a JSONPATH transformation to extract the desired field. Thus, the Channel will ignore the messages posted for some other device and only pass the messages for this device to the JSONPATH.
Based on my tests there is no error in the log when the REGEX does not match the message, which is exactly what we want.
When we are done, the Thing will look something like:
MQTT command topic: shellies/<shelly name>/command Custom On/Open value: announce Custom Off/Closed value: announce
<shelly name> with the name of your specific device which you can find on config web page for the device. You need to know this anyway to command the device. For example,
Any time the Switch linked to this Channel receives any sort of command, it will publish “announce” to the device’s command topic.
MQTT state topic: shellies/announce Incoming value transformations: REGEX:(.*<shelly name>.*)∩JSONPATH:$.ip
The trick is the REGEX needs to match the full message, hence the parens around the full expression. But we only want to pass on messages that include this device’s name. As above, replace
<shelly name> with the real name. For example
The rest of the fields in the JSON can be extracted in the same way using a different JSONPATH expression.
Obviously, this approach can be used in different and more powerful ways. For example, the REGEX can both filter and select just a portion of the message, not just filter the message. Any transformation can follow the REGEX. And more than two transformations can be chained. This should give us the same flexibility, if not more than the MQTT 1 REGEX filter.