MQTT - Multiple channels from single topic

I’ve recently bought Shelly plus 1, since it’s not yet supported by Shelly Binding I decided to integrate it using mqtt binding.
The way it works is that shelly creates one topic <shelly name>/events/rpc and publishes all events into it, So for example when temperature changes, shelly publishes following message:

{
  "src": "shellyplus1",
  "dst": "shellyplus1/events",
  "method": "NotifyStatus",
  "params": {
    "ts": 1643827043.79,
    "switch:0": {
      "id": 0,
      "temperature": {
        "tC": 52.79,
        "tF": 127.02
      }
    }
  }
}

When button is pressed, it sends message like this:

{
  "src": "shellyplus1",
  "dst": "shellyplus1/events",
  "method": "NotifyEvent",
  "params": {
    "ts": 1643826690.03,
    "events": [
      {
        "component": "input:0",
        "id": 0,
        "event": "single_push",
        "ts": 1643826690.03
      }
    ]
  }
}

So for temperature I created new Number channel on generic mqtt thing, set channel to shellyplus1/events/rpc and incoming transform to JSONPATH:$.params.switch:0.temperature.tC.

That seems to work fine (channel has proper value when shelly sends temperature message). The problem is that my log is absolutly spammed with warnings for each channel whenever shelly sends message that is not matched by the JSONPATH transformation:

2022-02-02 19:37:34.135 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.params.switch:0.temperature.tC' in '{"src":"shellyplus1","dst":"shellyplus1/events","method":"NotifyStatus","params":{"ts":1643827053.82,"sys":{"available_updates":null}}}'

I can set log level for ChannelStateTransformation to ERROR to get rid of it but I was wondering if there’s a better way of doing that, like tell the channel to ignore the message if jsonpath does not match?

See MQTT 2.5 M1+ How to implement the equivalent to MQTT1 REGEX filters

Alternatively you can also use js transformation to parse the json and check if a specific json path will exist.

The problem with the JS transformation approach is that it has to return something. And that something will replace the state of the Item linked to that channel, essentially wiping out the data stored in the Item when ever the Channel sees a message it doesn’t care about. The Regex transformation will return nothing if nothing matches and cause the Channel to ignore the message entirely if it isn’t one it cares about.

Thanks, that seems to do the trick (although it feels kinda clumsy matching json using regex).

Now I have a followup question - I’m trying to use the second “NotifyEvent” message for trigger channel. So I set transformation to REGEX:(.*NotifyEvent.*)∩JSONPATH:$.params.events[0].event and I’d expect to see message in events.log about channel triggering single_push, but it doesn’t seem to do anything. Am I missing something about trigger channels?

Think of the regex as a filter. You are just checking the JSON to see if it’s one you care about before processing it.

They don’t do anything unless you actually have a rule configured to be triggered by it.

I get it, it’s just that regex is not a great tool to match json unless it’s a very simple case. Since regex can match nothing I don’t understand why jsonpath can’t do the same.

Right, I didn’t realized that. After creating rule for the channel it works, thanks!