How do i evaluate an MQTT-telegram with a variable key

  • Platform information:
    • openHAB version: openHAB 2.5.7 Release Build
  • Issue of the topic:
    I use a Tasmota device with an MCP23017, which sends a MQTT-Telegram at each status-change of an input pin. The topic is always the same, but the JSON-content differs with each of the 16 input-pins (D0 to D15):
11:02:32 MQT: s30/stat/RESULT = {"Time":"2020-08-31T11:02:32","MCP230XX_INT":{"D0":1,"MS":7269044}}
11:02:32 MQT: s30/stat/RESULT = {"Event":"Done"}
11:02:34 MQT: s30/stat/RESULT = {"Time":"2020-08-31T11:02:34","MCP230XX_INT":{"D0":0,"MS":2489}}
11:02:34 MQT: s30/stat/RESULT = {"Event":"Done"}

So my idea was, to define a thing with one channel for each input-pin, each listens on the same MQTT topic but each with a different transformationPattern:

Type switch : In0b "Home IO In 0" [ stateTopic="s30/stat/RESULT", transformationPattern="JSONPATH:$.MCP230XX_INT.D0", on="0", off="1" ]
Type switch : In1b "Home IO In 1" [ stateTopic="s30/stat/RESULT", transformationPattern="JSONPATH:$.MCP230XX_INT.D1", on="0", off="1" ]
Type switch : In2b "Home IO In 2" [ stateTopic="s30/stat/RESULT", transformationPattern="JSONPATH:$.MCP230XX_INT.D2", on="0", off="1" ]
Type switch : In3b "Home IO In 3" [ stateTopic="s30/stat/RESULT", transformationPattern="JSONPATH:$.MCP230XX_INT.D3", on="0", off="1" ]

This generally works fine, but has the disadvantage, that with each MQTT telegramm, only one JSONPATH matches and the other 15 that do not match gives an Error Message. The same is with the telegram {“Event”:“Done”} which gives me another 16 “not match” Lines in the log file

2020-08-31 11:02:34.441 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.MCP230XX_INT.D9' in '{"Time":"2020-08-31T11:02:34","MCP230XX_INT":{"D14":0,"MS":2489}}'
2020-08-31 11:02:34.444 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.MCP230XX_INT.D7' in '{"Time":"2020-08-31T11:02:34","MCP230XX_INT":{"D14":0,"MS":2489}}'
2020-08-31 11:02:34.447 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.MCP230XX_INT.D1' in '{"Time":"2020-08-31T11:02:34","MCP230XX_INT":{"D14":0,"MS":2489}}'
2020-08-31 11:02:34.451 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.MCP230XX_INT.D11' in '{"Time":"2020-08-31T11:02:34","MCP230XX_INT":{"D14":0,"MS":2489}}'

2020-08-31 11:02:34.464 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.MCP230XX_INT.D8' in '{"Event":"Done"}'
2020-08-31 11:02:34.467 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.MCP230XX_INT.D6' in '{"Event":"Done"}'
2020-08-31 11:02:34.470 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.MCP230XX_INT.D0' in '{"Event":"Done"}'

Has anyone an idea, how to solve this problem elegant?

Thanks in advance
Michi

Example -

Thanks a lot rossko57,
your link exactly addresses my problem.

I prepended the JSONPATH with a REGEX in the channel definition:

Type switch : In0b  "Home IO In 0"     [ stateTopic="s30/stat/RESULT", transformationPattern="REGEX:(.*D0.*)∩JSONPATH:$.MCP230XX_INT.D0", on="1", off="0" ]
Type switch : In1b  "Home IO In 1"     [ stateTopic="s30/stat/RESULT", transformationPattern="REGEX:(.*D1.*)∩JSONPATH:$.MCP230XX_INT.D1", on="1", off="0" ]
... and so on ...

so that the JSONPATH is evaluated only if the REGEX matches and it works fine.

Again what learned :slight_smile:

Michi