# MQTT-nodes with dynamic topics

**URL:** <https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621>\
**Category:** General\
**Tags:** mqtt\
**Created:** [2 December 2024 11:30 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621 "2024-12-02T11:30:08Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![binderth](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/binderth/32/35124_2.png) [@binderth](https://discourse.nodered.org/u/binderth)\
**Post date:** [2 December 2024 11:30 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/1 "2024-12-02T11:30:08Z")

</div>

My use case is having a bunch of identical devices, which communicate via MQTT.

They have a few "channel", which communicate via the same topic structure:

```auto
* devices/device1/infoTopic1
* devices/device1/infoTopic2
* devices/device1/infoTopic3
* devices/device1/infoTopic4
* devices/device1/infoTopic25
* devices/device1/commandTopic1
* devices/device1/commandTopic2
* devices/device1/commandTopic12 

```

and

```auto
* devices/device2/infoTopic1
* devices/device2/infoTopic2
* devices/device2/infoTopic3
* devices/device2/infoTopic4
* devices/device2/infoTopic25
* devices/device2/commandTopic1
* devices/device2/commandTopic2
* devices/device2/commandTopic12

```

What I want to achieve is

1. copy the flow for device1 to one for device2
2. change a `flow.variable` ("device1" or "device2", ...)
3. be happy

If I use "dynamic subscription", then I have to add a for all 25 info-topics and 12 command-topics for each read or write action. Can I somehow use the "MQTT in"-node with some kinda logic so, that it just replaces the second part of the topic structure?

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [2 December 2024 11:49 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/2 "2024-12-02T11:49:29Z")

</div>

> [@binderth](#):
>
> If I use "dynamic subscription", then I have to add a for all 25 info-topics and 12 command-topics for each read or write action

You can hardcode the topic using a combination of variables (I think)

1. Set an environment variable on a group : `MY_TOPIC = 'device1'`
2. Add your MQTT Node(s), to this group
3. Set the topic name in the MQTT Node(s)

The below will subscribe to all topics of `device1`

```auto
devices/$(MY_TOPIC)/#

```

See : [Subscribe to a topic : Node-RED](https://cookbook.nodered.org/mqtt/subscribe-to-topic)

NOTE: I may have this completely wrong - I apologies if so (I don't do much MQTT)

---

<div class="post-metadata">

**Author:** ![hardillb](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hardillb/32/12373_2.png) [@hardillb](https://discourse.nodered.org/u/hardillb)\
**Post date:** [2 December 2024 12:02 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/3 "2024-12-02T12:02:20Z")

</div>

Environment Variable substitution only works for the whole field, it can not be used for part of a field

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [2 December 2024 12:03 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/4 "2024-12-02T12:03:38Z")

</div>

Thanks @hardillb

Should still be able to use that method still right?

```auto
MY_TOPIC = 'devices/device1/#'

```

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [2 December 2024 12:15 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/5 "2024-12-02T12:15:13Z")

</div>

You can't use `devices/$(MY_TOPIC)/#` but I think there's nothing to stop you setting MY\_TOPIC to "devices/device1/#" Not sure, I don't use environment variables like that.

How many MQTT-in and out nodes do you have - one for each device or one for each topic for each device? Are you using the + and # wildcards?

Just guessing that devices/device1/infoTopicnn is for messages from the device and devices/device1/commandTopicnn is for messages sent to it?

In this case I think your topics are not well structured because an MQTT-in node subscribing to devices/device1/# will get both kinds of message. You will need some way to filter out.  
It might be worth considering something like info/device1/01 ... info/device1/25 and command/device1/01 ... command/device1/12

---

<div class="post-metadata">

**Author:** ![binderth](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/binderth/32/35124_2.png) [@binderth](https://discourse.nodered.org/u/binderth)\
**Post date:** [2 December 2024 12:26 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/6 "2024-12-02T12:26:54Z")

</div>

Thanks for your help so far.

I've got more or less two main use cases:

1. A bunch of Tasmota devices
2. My two Kia EV6 electric cars, same model, same API, same everything

All of which more or less work the same, but (of course) should react to different topics for both info and command. So my thinking was initially simple: copy the flows and have them only differentiate with a variable aka "device name" in the topics. (Regardless the /info/# problem, that's a side quest so to speak! 😉 ).

As I can see, the current possibilities within MQTT-nodes are not prepared for this, so I either have to stick with my copied flows and change everything accordingly on ALL the flows. or to built a sophisticated entry for my both use cases, whithin one flow and distinguish the flows there. First one is kinda dull, because in case of changes, I'll have to do them in ALL as I said. Second one is kinda heavy-lifting to avoid changing them all.....

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [2 December 2024 14:35 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/7 "2024-12-02T14:35:21Z")

</div>

> [@marcus-j-davies](#):
>
> `MY_TOPIC = 'devices/device1/#'`

As Marcus suggest you can us `#` or also `+` to subscribe to multiple topics.

`devices/+/+`

]  
you can then spilit the topic

```auto
myDevice = msg.topic.split("/")

```

You can then use `myDevice[1]` to route to various flows using link call nodes, by setting

```auto
msg.target = myDevice[1]

```

---

<div class="post-metadata">

**Author:** ![gemini86](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gemini86/32/70967_2.png) [@gemini86](https://discourse.nodered.org/u/gemini86)\
**Post date:** [2 December 2024 18:16 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/8 "2024-12-02T18:16:24Z")

</div>

you can also just use a switch node:

msg.topic includes "device2" ---\> output 1.

---

<div class="post-metadata">

**Author:** ![binderth](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/binderth/32/35124_2.png) [@binderth](https://discourse.nodered.org/u/binderth)\
**Post date:** [3 December 2024 07:45 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/9 "2024-12-03T07:45:42Z")

</div>

After thinking about it for a moment. I did the following:

1. added the environment variable for each flow adding the name of the device to the flow
2. adding a function to build the writing and/or listening topics after each flow start
3. injecting the names to the "mqtt in"-nodes and used them for the "mqtt out" ones.

So I'm happy... for now, because I noticed, the node-red-contrib-bluelinky nodes for the car don't allow for dynamic subscription of cars ... yet. 😉 So, I do have to change each "car action" nevertheless per flow. But my logic is now able to use variables, which is good. No more messing around with JS-code nodes. at least that. Thanks for your help!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [3 March 2025 07:46 UTC](https://discourse.nodered.org/t/mqtt-nodes-with-dynamic-topics/93621/10 "2025-03-03T07:46:16Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
