# Beginner questions on IF expressions and wildcard usage in function node

**URL:** <https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999>\
**Category:** General\
**Created:** [3 September 2023 11:43 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999 "2023-09-03T11:43:38Z")\
**Posts on this page:** 20\
**Page:** 8

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [7 September 2023 20:53 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/142 "2023-09-07T20:53:09Z")

</div>

> [@Buckskin](#):
>
> `// try msg.payload[element].Time: msg.payload.Time,`

Unfortunately did not work either. Still an error symbol.

> [@Colin](#):
>
> Currently msg.payload is just a value (msg.payload[element]). If you want to have a property msg.payload.time then you must make the payload be an object

But payload is already an object.  
Incoming message is  
`{"topic":"raw_data/tasmota_D2EE70/SENSOR","payload":{"Time":"2023-09-07T22:51:07","ATC0d5c0c":{"mac":"a4c1380d5c0c","Temperature":21.5,"Humidity":63.2,"DewPoint":14.2,"Btn":0,"Battery":40,"RSSI":-71},"ATC4e211d":{"mac":"a4c1384e211d","Temperature":33.2,"Humidity":33.6,"DewPoint":15,"Btn":1,"Battery":82,"RSSI":-67},"TempUnit":"C"},"qos":0,"retain":false,"_msgid":"33ec289d8866a035"}`

and the outgoing is (when I remove the broken line of code):  
`{"topic":"tele/xiaomi/ATC4e211d","payload":{"mac":"a4c1384e211d","Temperature":33.2,"Humidity":33.6,"DewPoint":15,"Btn":1,"Battery":82,"RSSI":-67},"_msgid":"33ec289d8866a035"}`

So the incoming message has an object payload and the outgoing still does.  
All the node does is separate the incoming one into the individual devices. The payload remains an object.  
That's what is confusing me.

So all I want to do is add another property to that existing payload object under the respective ATC\*.  
So instead of this:  
`{"topic":"tele/xiaomi/ATC4e211d","payload":{"mac":"a4c1384e211d","Temperature":33.2,"Humidity":33.6,"DewPoint":15,"Btn":1,"Battery":82,"RSSI":-67},"_msgid":"33ec289d8866a035"}`  
I want to output this:  
`{"topic":"tele/xiaomi/ATC4e211d","payload":{"mac":"a4c1384e211d","Temperature":33.2,"Humidity":33.6,"DewPoint":15,"Btn":1,"Battery":82,"RSSI":-67},"_msgid":"33ec289d8866a035","Time":"2023-09-07T22:51:07"}`

---

<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:** [7 September 2023 21:10 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/143 "2023-09-07T21:10:11Z")

</div>

> [@AleXSR700](#):
>
> But payload is already an object.

Yes you are right, sorry. In that case you will have to put some code in to add that property before sending it.

```auto
matchingKeys.forEach((element) => {
    let newMsg = {
        topic: "tele/xiaomi/" + element,
        payload: msg.payload[element]
    }
    newMsg.time = msg.payload.time
    node.send(newMsg)
})

```

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [7 September 2023 21:27 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/144 "2023-09-07T21:27:34Z")

</div>

Interesting. Thank you!

But I am surprised that I have to put it in before sending it. Because I was changing the message while sending it before. So why is it allowed to change e.g. the topic while sending it but adding a property to an object while sending it is not allowed?

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [7 September 2023 22:16 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/145 "2023-09-07T22:16:57Z")

</div>

Okay, minor issue, I think:  
I am trying to work with [breaks in labeled blocks](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break?retiredLocale=de).  
The reason is simply that I have a bunch of `If ElseIf ElseIF ElseIf Else` and each `If/ElseIf` would have the same statements. Since I do not want to repeat them over and over, I was thinking of something like breaks in labeled blocks.

```auto
Commandblock: {
    Else { 
    IfBlock: {
        If blah Then Break IfBlock
        Else If Blah Then Break IfBlock
        Else Break Commandblock
   }}}

```

But it seems that a block always has to start with a declaration or statement. Is that correct? So am I forced to declare or state something just to use the block break?  
Or is there an alternative without that hurdle?

I thought I might be able to use [continue](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue?retiredLocale=de) but that is also "jump back up" rather than jump to something later in the code and also does not seem to work in front of `if`

And I cannot think of a switch case that would work.

I cannot find a `goTo()` function.

Is there nothing that allows me to jump somehwere else when using such a chain of if expressions?

---

<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:** [7 September 2023 22:54 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/146 "2023-09-07T22:54:50Z")

</div>

> [@AleXSR700](#):
>
> I want to work with [breaks in labeled blocks](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break?retiredLocale=de)

Why?

> [@AleXSR700](#):
>
> ```auto
> Commandblock: {
> Else { 
> IfBlock: {
> If blah Then Break IfBlock
> Else If Blah Then Break IfBlock
> Else Break Commandblock
> }}}
> 
> ```

What language does this pseudocode represent?

> [@AleXSR700](#):
>
> Is there nothing that allows me to jump somehwere else when using such a chain of if expressions?

Can you explain why if () and else if () coding does not suit?

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [7 September 2023 23:57 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/147 "2023-09-07T23:57:39Z")

</div>

> [@jbudd](#):
>
> What language does this pseudocode represent?

A mixture of JS and common language 😉

> [@jbudd](#):
>
> Can you explain why if () and else if () coding does not suit?

Because each IF condition is followed by a statement.  
Since the statement for each is the same, it would be lots of repeating code.

But using OR will not work because 1000\>100 and 1000\>50 and 1000\>10, so multiple conditions will be met in a top down approach.

```auto
            if (
                (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold5') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta5'))
                || (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold4') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta4'))
                || (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold3') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta3'))
                || (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold2') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta2'))
                || (msg.payload.ENERGY['Power'][0] < flow.get('Threshold2') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta1'))
            ){
                statements
            }

```

with threshold5\>4\>3\>2\>1 and powerdelta5\>4\>3\>2\>1.

What I think would theoretically work and be "elegant" would be exiting the IF and jumping to the statement via goto, continue or break (if the latter worked with If).

```auto
        Power0Block: {
        else { 
            Power0IFBlock: {
                    if (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold5') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta5')) { break Power0IFBlock } 
                    if (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold4') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta4')) { break Power0IFBlock } 
                    if (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold3') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta3')) { break Power0IFBlock } 
                    if (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold2') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta2')) { break Power0IFBlock } 
                    if (msg.payload.ENERGY['Power'][0] < flow.get('Threshold2') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta1')) { break Power0IFBlock } 
                    else {break Power0Block}
                    }
                {
                statements
                }
            }
        }

```

The alternative being the use of range or between(), but if I can I would prefer to work with just one limit per condition, i.e.  
`value > blah1` instead of `between(value, blah1, blah2)`

---

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [8 September 2023 00:17 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/148 "2023-09-08T00:17:34Z")

</div>

Could you explain what it is you are doing with the powerdelta logic ?

What is the ultimate purpose ?

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [8 September 2023 00:32 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/149 "2023-09-08T00:32:59Z")

</div>

Input value is power consumption or short "Power". That value is measured in Watts.

If the value is \> 1000 W I only want to know if it changes by more than 50 W. If the value is 1000\<value\<100 I want to know if it changes by 10 W. And so on.  
Threshold in this case is the 1000 or 100 and powerdelta is the 50 or 10.

So the larger the value of Power the larger the value of PowerDelta, i.e. the less interested I am in small changes.

---

<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:** [8 September 2023 01:49 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/150 "2023-09-08T01:49:29Z")

</div>

> [@AleXSR700](#):
>
> But using OR will not work because 1000\>100 and 1000\>50 and 1000\>10, so multiple conditions will be met in a top down approach.
> 
> ```auto
> if (
> (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold5') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta5'))
> || (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold4') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta4'))
> || (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold3') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta3'))
> || (msg.payload.ENERGY['Power'][0] >= flow.get('Threshold2') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta2'))
> || (msg.payload.ENERGY['Power'][0] < flow.get('Threshold2') && Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0')) >= flow.get('PowerDelta1'))
> ){
> statements
> }
> 
> ```

I think that if you have a chain of OR operators, evaluation will stop as soon as one is found which evaluates true so "multiple conditions will be met" is not a problem.  
That's not to say that this is the best way to code this program logic.

I consider that including _[5 copies of] all of these terms_ in an expression is taking code obfuscation a tad too far.  
`msg.payload.ENERGY['Power'][0]`  
`flow.get('ThresholdN')`  
`Math.abs(msg.payload.ENERGY['Power'][0] - flow.get(msg.topic + '_Power_0'))`  
`flow.get('PowerDeltaN')`

Imagine if a few months down the line you noticed that in some circumstances it does not work properly. Would you quickly spot that you have `flow.get('Threshold2')` on two lines and no `flow.get['Threshold1')`? Would you remember if this was by design, or could it be the bug?  
I presume it is by design.

If you used some shorter aliases it would be a bit more readable - something like this?

```auto
const Pwr = msg.payload.ENERGY['Power'][0]
const LastPwr = flow.get(msg.topic + '_Power_0') ?? 0

const T1 = flow.get('Threshold1') ?? 0
const T2 = flow.get('Threshold2') ?? 0
const T3 = flow.get('Threshold3') ?? 0
const T4 = flow.get('Threshold4') ?? 0
const T5 = flow.get('Threshold5') ?? 0

const D1 = flow.get('PowerDelta1') ?? 0
const D2 = flow.get('PowerDelta2') ?? 0
const D3 = flow.get('PowerDelta3') ?? 0
const D4 = flow.get('PowerDelta4') ?? 0
const D5 = flow.get('PowerDelta5') ?? 0

const Diff = Math.abs(Pwr - LastPwr)

if (
     ((Pwr >= T5) && (Diff >= D5))
  || ((Pwr >= T4) && (Diff >= D4))
  || ((Pwr >= T3) && (Diff >= D3))
  || ((Pwr >= T2) && (Diff >= D2))
  || ((Pwr < T2) && (Diff >= D1))
 )

```

---

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [8 September 2023 02:27 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/151 "2023-09-08T02:27:57Z")

</div>

> [@AleXSR700](#):
>
> the less interested I am in small changes

I get that but what are you doing with the information, i.e. why does it matter how big the change is ?

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [8 September 2023 06:23 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/152 "2023-09-08T06:23:18Z")

</div>

Or maybe use a % change so it automatically varies ?

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [8 September 2023 06:59 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/153 "2023-09-08T06:59:41Z")

</div>

> [@dceejay](#):
>
> Or maybe use a % change so it automatically varies ?

Good idea, but unfortunately no. I used to use a combination of relative and absolute changes, but there is not one value that fits all. So for my switch to Node-RED I decided to stop using both and only use absolute changes.

> [@Sean-McG](#):
>
> I get that but what are you doing with the information, i.e. why does it matter how big the change is ?

Ah, the question of all questions 🙂  
The short answer is: database size increase due to redundant information.

The longer answer:  
I have hundreds of entities ([see info on device, entity etc.](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/43)) which are all being tracked and their data recorded. Home Assistant is very limited in letting me restrict what is being recorded. It will not record values that are identical to the previous one and I can select which entities to record.  
But, identical means identical. So a power sensor that varies by x.1 or x.x1 will trigger a database write. And sensors and consumers do not consume that constantly. Same for room temperatures and humidity.

So I have three options:

- Increase the interval of publish on the devices. This has the disadvantage that I will not register spikes or sudden changes (e.g. a microwave consumes all power in just 2 min which will rarely be seen properly if the interval is 5 min)

- Decrease the resolution of the devices (e.g. only send integer values for Temperature) but that does not work for all and is again not precise when I want it to be.

- Filter the source data --\> in come Node-RED 🙌

> [@jbudd](#):
>
> I think that if you have a chain of OR operators, evaluation will stop as soon as one is found which evaluates true so "multiple conditions will be met" is not a problem.

True, but you are forgetting the PowerDelta criteria. Key is that for large values the PowerDelta is the crucial condition.  
Example: `1500 W consumer`

```auto
If (1500 > 1000 && 1500-1490 > 50) // false due to powerdelta
ElseIF (1500 > 100 && 1500-1490 >20 ) // false due to powerdelta
ElseIf (1500 > 10 && 1500-1490 > 5) // TRUE

```

As you can see, that is clearly not the intended outcome 🙂  
[EDIT: Forgot to add the elseif to the breaking condition in my previous post but would need it to prevent this exact behavior]

> [@jbudd](#):
>
> I consider that including _[5 copies of] all of these terms_ in an expression is taking code obfuscation a tad too far.

Yes, probably, but  
a) I do not like to declare a bunch of constants just because Node-RED does not follow the general approach of being able to use global (here flow context) variables without a long command)  
b) it forces me to look up the values twice (once in the declaration of the constant inside the flow... to see if that is correct... and a second time to get the actual value from the flow context initialization node).

I will use the `between(value, x, y)` if I need to, although I dislike it a lot (adds even more long flow.get() and more possibilites for errors) if no one can think of a working `break` or `continue`alternative.

Or does anybody know a short statement that consumes almost no computing power (and ideally no write cycles to memory) which I can abuse to make Node-RED accept my break approach?  
I tried a simple `let i=0` but it complained that I was not using it later 😃

EDIT: The more I think about it, the more complicated it gets to make the code short but fully working. So I may need to bite one of the many bullets in the end ☹

---

<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:** [8 September 2023 08:26 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/154 "2023-09-08T08:26:28Z")

</div>

> [@AleXSR700](#):
>
> True, but you are forgetting the PowerDelta criteria. Key is that for large values the PowerDelta is the crucial condition.  
> Example: `1500 W consumer`
> 
> ```auto
> If (1500 > 1000 && 1500-1490 > 50) // false due to powerdelta
> ElseIF (1500 > 100 && 1500-1490 >20 ) // false due to powerdelta
> ElseIf (1500 > 10 && 1500-1490 > 5) // TRUE
> 
> ```
> 
> As you can see, that is clearly not the intended outcome 🙂

Good example.  
What if you wrote it the other way round?

```auto
if (1500 <= 10) false
else if (1500 <= 100 && 1500 - 1490 > 5) false
else if (1500 <= 1000 && 1500 - 1490 > 20) false
else if ( 1500 - 1490 > 50) false 

```

Until I have had coffee I can't tell if that works for all values.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [8 September 2023 08:44 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/155 "2023-09-08T08:44:05Z")

</div>

Bottom up....hmmmm... I know I scrapped that in my tasmota approach for some reason, but it might have been tasmota feature or syntax related...

Hmmmmm.....I will think about it during breakfast 👍 🙂

---

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [8 September 2023 12:32 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/157 "2023-09-08T12:32:22Z")

</div>

> [@AleXSR700](#):
>
> (e.g. a microwave consumes all power in just 2 min which will rarely be seen properly if the interval is 5 min)

I think most people here do not use HA, and while happy to help with your specific programming questions, we don't have knowledge of HA. However I'm also sure that most people posting in this thread will also be recording many data points, so its not a unique task. Typically people tend to use something like InfluxDB and grafana to store and view metrics like this.

I believe you are using Tasmota for energy monitoring, using the active power property ?

Each device also has an Energy Total property. Taking you microwave example above, most of the time it will consume almost nothing, but there may be slight variations of reported active power.

If however you use the Energy Total figure you could easily subtract the last reading to find out how much was consumed in a given period. Nothing will be missed and you can set the interval to suit your needs.

This is how I store consumption at 5min intervals per device. to save disk space after 30 days this data is aggregated to 1hour intervals.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [8 September 2023 12:36 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/158 "2023-09-08T12:36:33Z")

</div>

Yes, it is similar in HA where I switched to the built in SQLite because InfluxDB was not really properly implemented in the dashboard/lovelace cards.

But basically it is the same approach.  
Unfortunately the built in cards don't really work like Grafana. They are more user friendly but subtracting data points is usually not supported without templating or worse.

That's why I am directly using ENERGY Power as my data points rather than creating them as a mean from ENERGY Total.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [8 September 2023 16:02 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/160 "2023-09-08T16:02:55Z")

</div>

I would like to ensure that I only ever change those properties of a message that I want to actively change. Everything else should just be passed through.

We discussed earlier that in a forEach() I would be overwriting the original msg.topic if I use the `=` instead of `:` approach.

Would this also apply here?

```auto
const matchingKeys = Object.keys(msg.payload).filter((element) => element.startsWith("ATC"))
matchingKeys.forEach((element) => {
    let newMsg = {
        topic: "tele/xiaomi/" + element,
        payload: msg.payload[element]
    }
    newMsg.payload.Time = msg.payload.Time
    node.send(newMsg)
})

```

Or would, because I am defining a newMsg, the original topic not be changed and the forEach would continue to function if I replaced the `:` expressions with `=` expressions (for payload and topic)?

Or, if the problem remains, could I somehow define something like `msg: msg` to preserve everything except what I replace afterwards?

```auto
    let newMsg = {
        msg: msg
        topic: "tele/xiaomi/" + element,
        payload: msg.payload[element]
    }

```

---

<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:** [8 September 2023 16:42 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/161 "2023-09-08T16:42:59Z")

</div>

I think that is where we started, using cloneMsg, but you said you didn't want to do that because it would consume more resources.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [8 September 2023 18:05 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/162 "2023-09-08T18:05:51Z")

</div>

You are right, it was the cloning!

I will implement that now that I needed the `let newMsg` anyway.

Thank you again 🙂

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [8 September 2023 20:51 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/163 "2023-09-08T20:51:39Z")

</div>

So, hopefully the last challenge of this project: synchronize something asynchronous.

I need to write a function that waits for incoming messages.  
I know the join node has this functionality in a basic manner. Is there a template somewhere how the wait function works?

I need to wait until each of the nodes wired into the input has delivered a message with identical msg.topic and msg.Time.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/4/e4bf3ea977d1a5a494addc633a95e8c542638d08.png)

Once I have received one message from each source node, I will perform the actual task.

Each of the three source nodes will always output a message with the same msg.topic and msg.Time. But since Node-RED is asynchronous, I need to check for reception of those three.

[Previous page](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999.md?page=7)

[Next page](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999.md?page=9)
