MQTT JSONPATH transformation filter not working as expected

  • Platform information:
    • Hardware: IntelNUC, 16GB, 4 Cored
    • OS: Ubuntu 22.04.LTS
    • Java Runtime Environment: 17.0.14
    • openHAB version: 4.3.5 (official docker build)

What is the environment / scene of my configuration issue?

I have equipped several of my rollershutters with Shelly switches to open / close them. Using the Astro binding together with data from PV and outdoor temperature I can already close the rollershutters on east, south and west side of the house dependant on the temperature and amount of sunlight: When it’s warm and the sun is intensively shining, the rollershutters will shade my rooms. However, when someone in the room decides that they want more sunlight and manually opens the shades, the automation will shortly after close the shades again.

So I thought that, when someone is manually modifying the shading state, this will pause the automation for that very shutter until the next day.

That’s why I am trying to capture the state of the Shelly Plus 2PM input buttons using mqtt and some JSONPATH transformation. The Shelly is configured as rollershutter. I know that I can get this status also with the Shelly binding, but in my whacky WiFi environment, mqtt turned out to be more reliable in general.

That’s the current mqtt thing configuration:

Thing mqtt:topic:shellyplus2pm-e465b8f349cc "shellyplus2pm-e465b8f349cc"    (mqtt:broker:mosquitto)  [availabilityTopic="shellyplus2pm-e465b8f349cc/online", payloadAvailable="true", payloadNotAvailable="false"] {
    Channels:
    Type number : temperatureC  "Temperatur °C"         [ stateTopic="shellyplus2pm-e465b8f349cc/status/cover:0", transformationPattern="JSONPATH:$.temperature.tC" ]
    Type number : temperatureF  "Temperatur °F"         [ stateTopic="shellyplus2pm-e465b8f349cc/status/cover:0", transformationPattern="JSONPATH:$.temperature.tF" ]
    Type number : currentPos    "Aktuelle Position"     [ stateTopic="shellyplus2pm-e465b8f349cc/status/cover:0", transformationPattern="JSONPATH:$.current_pos" ]
    Type switch : input0       "Input 0"                [ stateTopic="shellyplus2pm-e465b8f349cc/events/rpc", transformationPattern="JSONPATH:$.params.events[?@.component==\"input:0\"].event", on="single_push", off="" ]
    Type switch : input1       "Input 1"                [ stateTopic="shellyplus2pm-e465b8f349cc/events/rpc", transformationPattern="JSONPATH:$.params.events[?@.component==\"input:1\"].event", on="single_push", off="" ]
}

The configuration for the two switches input0 and input does not yet deliver the results, I want.

When pressing the wall switch for up direction, that closes input 0 on the device and down direction closes input 1 direction. The rollershutter works correctly.

Closing either input 0 or input 1 yields the following similar mqtt message (exchange “input:0” with “input:1” for physical input 1 on the shelly):

{
    "src":"shellyplus2pm-e465b8f349cc",
    "dst":"shellyplus2pm-e465b8f349cc/events",
    "method":"NotifyEvent",
    "params":{
        "ts":1754130093.20,
        "events":[
            {
                "component":"input:0",
                "id":0,
                "event":"single_push",
                "ts":1754130093.20
            }
        ]
    }
}

Developing the JSONPATH expression with jsonpath.com resulted in this JSONPATH expression that delivers the value of “event” (one could leave out “@.event==’single_push’” to get the same result though):

$.params.events[?@.component=='input:0' && @.event=='single_push'].event

Shortly after the button is released (input 0 is opened again), the mqtt message is:

{
    "src":"shellyplus2pm-e465b8f349cc",
    "dst":"shellyplus2pm-e465b8f349cc/events",
    "method":"NotifyStatus",
    "params":{
        "ts":1754137800.00,
        "cover:0":{
            "aenergy":{
                "by_minute":[0.000,0.000,0.000],
                "minute_ts":1754137800,
                "total":82.187
            }
        }
    }
}

So, this message does not have the events section at all.

Using the Thing configuration as above and setting the mqtt binding log level to debug, I get this in the log. There’s no mention of “transformation resulted in” after these messages. But also no info why it may have failed.

2025-08-02 13:31:17.911 [DEBUG] [ternal.JSonPathTransformationService] - about to transform '{"src":"shellyplus2pm-e465b8f349cc","dst":"shellyplus2pm-e465b8f349cc/events","method":"NotifyEvent","params":{"ts":1754134277.90,"events":[{"component":"input:0","id":0,"event":"single_push","ts":1754134277.90}]}}' by the function '$.params.events[?@.component=="input:0"].event'
2025-08-02 13:31:17.912 [DEBUG] [ternal.JSonPathTransformationService] - about to transform '{"src":"shellyplus2pm-e465b8f349cc","dst":"shellyplus2pm-e465b8f349cc/events","method":"NotifyEvent","params":{"ts":1754134277.90,"events":[{"component":"input:0","id":0,"event":"single_push","ts":1754134277.90}]}}' by the function '$.params.events[?@.component=="input:1"].event'

What do I want to archieve?

  • When the events section for input:0 / input:1 has an event with value “single_push”, the Switch channel input0 / input1 should recognize this as “ON”. All other states should be recognized as “OFF”.

What am I doing wrong? Am I on the correct path on approaching this issue at all?

Best regards

Marco

Maybe not an answer to the question, but I’m wondering why you are not using the Shelly binding? If your device is not supported, it maybe in 4.3.6 or 5.0.0 as that binding has been undergoing some great fixes lately.

I ask this as this may prevent you from all the json stuff and just use the available channels, way simpler.

Hi,

you can $.params.events[?(@.event=='single_push')].id as trigger !?

I’m also using mqtt for my shelly 1 devices for stability reasons.
For reading mqtt messages I’m using MQTT-Explorer.
For many MQTT channels I’m using javascript files to retrieve input or generate output.

Instead of setting value transformations as JSONPATH:$… I’m using value transformations JS:NameOfMyTransformationFile.js The transformation files are in the transform sub directory of the openHabs conf directory. Here is as sample file:

// example input of IKEA bulb: {"brightness":198,"color":{"x":0.7006,"y":0.2993},"color_mode":"xy","color_temp":250
(function(color){
//  console.info('zigbeeColorIN.js (in)', color)
  var ret = ''
  try {
    var colorDict =  JSON.parse(color)
    //console.info('zigbeeColorIN.js (parsed in)', colorDict.color.x, colorDict.color.y, colorDict.brightness, colorDict.state)
    // convert 254 Steps to 100% of brightness
    var bright = Math.round(colorDict.brightness / 2.54);
    // example output to openHAB: x,y,brightness - f.e.: 0.6942,0.2963,50
    ret = colorDict.color.x + "," + colorDict.color.y + "," + bright
  }
  catch(SyntaxError) {
    console.warn("zigbeeColorIN SyntaxError input", color)
  }
    //console.info("zigbeeColorIN output", ret)
	return ret;
})(input)

This sample script file converts brightness (0:255) of an IKEA bulb to percentage used by openHab. I'm using JSON.stringify(...) when I convert i.e. a dictionary to a string sent do mqtt. You may look for detailed explanations in the community.

Hi @lsiepel ,

I’ll give the Shelly Binding in OH 5.0.0 a try.

Just switched my docker instance to the new version and will monitor how it’s going. So far, it caught the input switch events flawlessly.

Best regard

Marco

Hi @Manni51 ,

that looks like a nice approach given that JS is much more powerful. I’ll keep that in mind for those Shellies that have a poor WiFi connection.

Maybe Shelly also fixes my problem inadvertently in a new firmware version: I’ve just bought a few 2PM gen3 (Plus 2PM was out of stock) and the Gen3-devices have their own state topic for the input contacts:

Type switch : input0       "Input 0"                [ stateTopic="shelly2pmg3-e4b3233f6044/status/input:0", transformationPattern="JSONPATH:$.state", on="true", off="false" ]

Thus, the simple JSONPATH stuff works here.

Best regards

Marco

okay, firmware version 1.3.3 had the separate topics for input 0 / input 1.

Version 1.6.2 does not have them (at least for Plus 2PM) and version 1.7.0-beta4 has them again :man_shrugging:t3:

Interesting maybe for @markus7017 as a fix for the 1.6 fw has been merged

the binding does not use mqtt