# Extract mqtt topic json

**URL:** https://discourse.nodered.org/t/extract-mqtt-topic-json/54026
**Category:** General
**Created:** [20 November 2021 10:13 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026 "2021-11-20T10:13:00Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![trombose009](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trombose009/32/30787_2.png) [@trombose009](https://discourse.nodered.org/u/trombose009)
#### Post date: [20 November 2021 10:13 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/1 "2021-11-20T10:13:00Z")

</div>

Hey guys,

I am using node-red to extract a mqtt message to write the values into influxdb.  
It works very well and looks like this:

```auto
let thisRoom = msg.topic.split("/")[2]
msg.payload = [{temp: msg.payload.temp, hum: msg.payload.hum},{room: thisRoom}]
return msg

```

Now, I have a new sensor which is not transmitting humidity. but the topic structure have to be the same.  
So, at the moment, I get an error because no hum value exists.  
Is it possible to change this script to make it able to do both kinds of mqtt messages?  
If it is possible, I won't like to use a seperate flow or a new topic structure.

[screenshot|254x500](https://discourse.nodered.org/uploads/short-url/lMnzae2mXqlcp72TJzz19VHL5jb.jpeg)

---

<div class="post-metadata">

### Author: ![ScheepersJohan](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scheepersjohan/32/39556_2.png) [@ScheepersJohan](https://discourse.nodered.org/u/ScheepersJohan)
#### Post date: [20 November 2021 10:21 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/2 "2021-11-20T10:21:15Z")

</div>

In a function node

```auto
let hum = msg.payload.[0]hum

if(typeof hum === "undefined"){
    hum = 0
}

msg.payload.[0]hum = hum

```

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [20 November 2021 10:39 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/3 "2021-11-20T10:39:24Z")

</div>

If there is no humidity value then preferably you should not save it to a Measurement that normally includes temp and hum as this means that your db is full of empty holes, which is inefficient. Possibly the best way would be to split it into two measurements, temp and hum, and feed values to both measurements for those sensors that have humidity and only to the temp one for those without humidity.

---

<div class="post-metadata">

### Author: ![trombose009](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trombose009/32/30787_2.png) [@trombose009](https://discourse.nodered.org/u/trombose009)
#### Post date: [20 November 2021 11:36 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/4 "2021-11-20T11:36:52Z")

</div>

still this error:

Error: A 400 Bad Request error occurred: {"error":"unable to parse 'sensormeasure,room=sau hum=undefined,temp=7.01': invalid boolean"}

is this correct:

```auto
let thisRoom = msg.topic.split("/")[2]
if(typeof hum == "undefined"){
    hum = 0
}
msg.payload = [{temp: msg.payload.temp, hum: msg.payload.hum},{room: thisRoom}]
return msg

```

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [20 November 2021 12:20 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/5 "2021-11-20T12:20:49Z")

</div>

If you feed the output of that into a function node you will see that it is still showing `hum: undefined`. It is always best when testing to add a debug node to the output of the node you are changing to see what comes out.

I think, if you do want them all to go to the same measurement even though you will end up with a db full of holes, then you need something like

```auto
let thisRoom = msg.topic.split("/")[2]
const hum = msg.payload.hum
msg.payload = [{temp: msg.payload.temp},{room: thisRoom}]
// add the humidity into the message if it exists
if(typeof hum != "undefined"){
    msg.payload[0].hum = hum
}
return msg

```

Check in a debug node that this gives what you expect before connecting it to the db.

---

<div class="post-metadata">

### Author: ![trombose009](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trombose009/32/30787_2.png) [@trombose009](https://discourse.nodered.org/u/trombose009)
#### Post date: [20 November 2021 12:38 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/6 "2021-11-20T12:38:41Z")

</div>

> [@Colin](#):
>
> ```auto
> let thisRoom = msg.topic.split("/")[2]
> const hum = msg.payload.hum
> msg.payload = [{temp: msg.payload.temp},{room: thisRoom}]
> // add the humidity into the message if it exists
> if(typeof hum != "undefined"){
> msg.payload[0].hum = hum
> }
> return msg
> 
> ```

that's it, thank you!

yeah, maybe it is not absolutly clean. but hey, I planed to do the humidity measurement in that room too. I have just messed up the order for the sensor. So my sensor is not able to do the humidity measurement. Maybe I replace it sometime.

Or do you think it's better to write a "0" instead of just nothing like now?

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [20 November 2021 13:40 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/7 "2021-11-20T13:40:17Z")

</div>

> [@trombose009](#):
>
> do you think it's better to write a "0" instead of just nothing like now

Is the humidity in that room 0 or unknown? My take would be that the answer to that question determines what should go in the database.

---

<div class="post-metadata">

### Author: ![trombose009](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trombose009/32/30787_2.png) [@trombose009](https://discourse.nodered.org/u/trombose009)
#### Post date: [20 November 2021 13:53 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/8 "2021-11-20T13:53:41Z")

</div>

> [@Colin](#):
>
> database

unknown...

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [20 November 2021 14:24 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/9 "2021-11-20T14:24:57Z")

</div>

It was intended to be a rhetorical question, to suggest whether zero or nothing should go in the db. I would say don't put zero in the db unless the value is zero. If you don't know what it is then don't put anything in.

---

<div class="post-metadata">

### Author: ![trombose009](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trombose009/32/30787_2.png) [@trombose009](https://discourse.nodered.org/u/trombose009)
#### Post date: [20 November 2021 15:12 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/10 "2021-11-20T15:12:21Z")

</div>

🙂  
thank you colin,  
I know you are an expert and you did help me a lot in the past and also this time. but i am not sure if it is worth to change my db that much just because of this guinea pig barn sensor.... 😕

or do I just have to add some kind of measurement2 and ask you for the filtering function? I can do a bit C++ Arduino programming but I am not into this function scripting in node-red so I have to ask for everything. feels bad man.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [20 November 2021 15:52 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/11 "2021-11-20T15:52:23Z")

</div>

If you are intending to add the humidity sensor at some point then don't worry about it, keep it as you have it.

---

<div class="post-metadata">

### Author: ![trombose009](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trombose009/32/30787_2.png) [@trombose009](https://discourse.nodered.org/u/trombose009)
#### Post date: [20 November 2021 15:59 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/12 "2021-11-20T15:59:15Z")

</div>

lol  
I fear the will never happen. to be honest, i placed that device in the barn and as long as it is working well, the motivation to replace it is not really existant 🤔

maybe I should give it a try.  
So you suggest not to change the temp/hum sensors. Just to add a new flow in node-red which filters the room "sau" and write only the temp.

1.) So, therefore I have to change the function of my temp/hum flow in that kind, that they do not try to process date from the topic "sensors/room/sau".  
at the moment they respond on "sensors/room/#". So before I switched to your code today, they throw an error everytime the message to "sensors/room/sau" arrived. That was not a desaster but it is also not very clean.

2.) I have to add a flow only for "sensors/room/sau". I think I am able to do that by myself. at least I hope so.

Is that correct or do I misunderstood you maybe?

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [20 November 2021 16:29 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/13 "2021-11-20T16:29:20Z")

</div>

> [@trombose009](#):
>
> not to change the temp/hum sensors

You just need one flow, but it should send all temperature data to one measurement and humidity to another. You can do that by making it send one or two messages.

```auto
let thisRoom = msg.topic.split("/")[2]
const hum = msg.payload.hum
const temp = msg.payload.temp
let messages = []
if(typeof temp != "undefined"){
  let newMsg1= {}
  newMsg1.payload = [{value: msg.payload.temp},{room: thisRoom}]
  newMsg1.measurement = "temp"
  messages.push(newMsg1)
}
if(typeof hum != "undefined"){
  let newMsg2= {}
  newMsg2.payload = [{value: msg.payload.hum},{room: thisRoom}]
  newMsg2.measurement = "hum"
  messages.push(newMsg2)
}
return [messages]

```

That will cope with either one of both values present, passing on one or two messages as appropriate. The convention if you just have one value in a measurement is to call the value 'value' as what it is is identified by the measurement name. You will need to clear the measurement name in the influx node so that it will use the measurement name from the messages.

---

<div class="post-metadata">

### Author: ![RootShell-coder](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rootshell-coder/32/47167_2.png) [@RootShell-coder](https://discourse.nodered.org/u/RootShell-coder)
#### Post date: [20 November 2021 18:10 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/14 "2021-11-20T18:10:16Z")

</div>

I got curious and played around with the code a bit.  
sorry 😳

```auto
let thisRoom = msg.topic.split("/")[2] ?? "other room"
msg.payload = [{temp: msg.payload?.temp, hum: msg.payload?.hum},{room: thisRoom}]
return msg

```

it still returns "undefined", but without an error in the debug window

---

<div class="post-metadata">

### Author: ![trombose009](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trombose009/32/30787_2.png) [@trombose009](https://discourse.nodered.org/u/trombose009)
#### Post date: [20 November 2021 19:05 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/15 "2021-11-20T19:05:10Z")

</div>

Hey, that seems to work and I can add it to my existing graphs.

Let's wait one or two days. I'll let you know!

💓

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [20 November 2021 22:08 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/16 "2021-11-20T22:08:09Z")

</div>

> [@RootShell-coder](#):
>
> `msg.payload = [{temp: msg.payload?.temp, hum: msg.payload?.hum},{room: thisRoom}]`

The Optional Chaining operator `?.` tests the _preceding_ property to see if it exists, so in that code you are testing msg.payload, which will always exist (in this context). So that line is exactly the same as  
`msg.payload = [{temp: msg.payload.temp, hum: msg.payload.hum},{room: thisRoom}]`

---

<div class="post-metadata">

### Author: ![RootShell-coder](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rootshell-coder/32/47167_2.png) [@RootShell-coder](https://discourse.nodered.org/u/RootShell-coder)
#### Post date: [20 November 2021 23:30 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/17 "2021-11-20T23:30:29Z")

</div>

yeah 😇. It will remain undefined, but it will suppress the error output to the debug window.  
_Sorry, just a bad joke._

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [21 November 2021 08:45 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/18 "2021-11-21T08:45:46Z")

</div>

> [@RootShell-coder](#):
>
> it will suppress the error output to the debug window

Which error?

---

<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: [5 December 2021 08:46 UTC](https://discourse.nodered.org/t/extract-mqtt-topic-json/54026/19 "2021-12-05T08:46:26Z")

</div>

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