tg44 / mqtt-transformer

A simple service which consumes, transforms and periodically republish json messages on mqtt.
MIT License
14 stars 5 forks source link

Accessing matched fromTopic name segment in toTopic #8

Closed ginkel closed 2 years ago

ginkel commented 2 years ago

Hello again,

let's say, I have multiple MQTT topics that contain scalar values that I'd like to map to JSON and re-publish on distinct topics.

How would I achieve this without having to define a transform per source topic?

ATM I do have the following config snippet (imagine this being JSON, the YAML will automatically be transformed during deployment):

  transforms:
    - fromTopic: zigbee2mqtt/+/availability
      toTopic: zigbee_availability
      emitType: map
      wrapper: availability
      template:
        availability:
          $eval: availability

Is there a way to access the topic name fragment matched by the + from the toTopic?

Thanks, Thilo

tg44 commented 2 years ago

Currently, there is no mode for getting the topic names. But I will check how hard it is to give into the template.

tg44 commented 2 years ago

Hmmm, probably I don't get the problem you have.

I can add in the matched topic name, and you can split/transform it. But currently, we have no operators to relay to outgoing topics with logic from incoming data.

So I will add two things;

ginkel commented 2 years ago

Let me tray to explain my scenario in more detail: I have a couple of topics:

I'd like to map what's in these topics and publish the result on distinct topics

Ideally, w/o having to create multiple transforms.

tg44 commented 2 years ago

I added two new fields.

"topicKeyToMessage": "topic", will inject the input json a new "topic": "tele/asd/STATE" field according to the topic.

"toTopicTemplate": "${topic}_NEW", will push it to the templated topic instead of a fix one

{
            "fromTopic": "tele/+/STATE",
            "toTopicTemplate": "${topic}_NEW",
            "emitInterval": 60,
            "topicKeyToMessage": "topic",
            "emitType": "repeat",
            "template": {"uptime": {"$eval": "UptimeSec"}, "topic": {"$eval": "topic"}}
}

Will result;

=> tele/tasmota/STATE
{"UptimeSec": 29}
<= tele/tasmota/STATE_NEW
{"uptime":29,"topic":"tele/tasmota/STATE"}

If you can describe a good (common?) use-case, I would be glad to accept it as a recipe in the docs :) Probably the split and array function example would be powerful.

tg44 commented 2 years ago

@ginkel is this working for you now?

tg44 commented 2 years ago

Closing due inactivity. I think it is done anyways.