Beginner questions on IF expressions and wildcard usage in function node

You are expecting up to 500 messages per second, so does "with identical msg.Time" require millisecond precision?
At what point in your flow do you assign a value to msg.Time?

:thinking:

msg.Time will have 10 second intervalls. So the supplied precision of the normal comparison should suffice.
msg.Time is set before the three source nodes.

You mean because I say "basic manner"? If so, I mean that you can only use one criteria for the wait. So as long as the msg.topic is identical, each new msg will be counted for the wait count even if two messages from the same node are received with different msg.Time values.

Highly unlikely case given the 10 second update interval, but that interval may change at some point and then become an issue.

I am curious for the solution, but if it is really complicated, then I do not want you all to spend too much time on it.
I am merging the three nodes right now to handle the issue within one function node.

But as I say, I would be curious how to solve this issue in the future :slight_smile:

The thoughtful face is because it struck me that maybe, since you are seeking to do this project without standard Node-red nodes, you should consider doing all of your processing in an external program, C maybe, called via an exec node.

I have been trying to use standard nodes, but I usually cannot get the task done.

I am using some standard nodes and I do very, very much enjoy the possibility to "arrange" my code by having each segment encapsuled in a node.

So I am thoroughly enjoying myself right now :heart_eyes:

And then I get annoyed by something that is probably a teeenie tiny brain fart.

So, I am stuck debugging.

I have a nested if

if (condition1) {
  if (condition2) {
    msg.Power2Delta = Math.abs(msg.payload.ENERGY['Power'][2] - flow.get(msg.topic + '_Power2'))
    context.set(msg.topic + '_Update2Value', msg.payload.ENERGY['Power'][2])
  }
msg.payload.ENERGY['Power'] = context.get(msg.topic + '_Update2Value')
return msg
}

I would think the msg that is output from that node would contain a msg property called Power2Delta. But it does not.
It does, however, have the correct value for msg.payload.ENERGY['Power']

So both if statements are executed. But for some reason the change to the msg in the nested if statement (i.e. creation of property Power2Delta) is not transferred to the outer if expression, i.e. to the msg that is later being returned.

I cannot figure out why :frowning:

How do you know? You could confirm it with node.warn statements.

if (condition1) {
  node.warn("first if")
  if (condition2) {    
    node.warn("second if")
    msg.Power2Delta = Math.abs(msg.payload.ENERGY['Power'][2] - flow.get(msg.topic + '_Power2'))
    context.set(msg.topic + '_Update2Value', msg.payload.ENERGY['Power'][2])
  }
msg.payload.ENERGY['Power'] = context.get(msg.topic + '_UpdateValue')
return msg
}

The context variable you set in line 4 contains "_Update2Value" while the one you read in line 6 contains "_UpdateValue". Is this right?

I set a fake value for the UpdateValue and saw that it is being used.

I will correct in my post, that was a typo.

EDIT:
Used the node.warn() and I can see the info for both.

I think I fixed it with a debugging session. Not sure what was the root cause. I must have had missed some tiny detail somewhere.

But I will test with a real device now and monitor the behaviour.

Quick question:
Is it possible to only show the debug messages in the console of the flow I am currently in?

Probably well past the multiple if .. else issues but why not use switch

I could not get all combinations into the switch. Switch only accepts one control parameter, if I am not mistaken.

Is it possible to trigger an mqtt in node the way you trigger a function?

I have an mqtt in node that subscribes to a topic which is not regularly updated but has retained messages.
Whenever I deploy, the mqtt in reads the messages.

I would like to manually restart reading of those retained messages.

That is not really what MQTT is designed for. It is kinda possible by disconnecting/reconnecting but that is a nasty hack. Ultimately, MQTT is PUB/SUB by design.

You should store the retained message in your context and access that as and when required.

That is exactly what I am doing and exactly why I need to trigger manually: when I delete the flow contexts, the stored retained messages also get deleted.

Maybe I will turn them into global. Don't really need them as globals, but...well....I need a solution :slight_smile:

Then dont delete that one :person_shrugging:

Or, better still, as i suggested before, put all of the context vars you want to delete in a single object, then you only delete that one object.


Yuk

Exactly, yuk!

Well, the problem is, that I want to wipe those also. I am playing with topics and I need to wipe all flow contexts but I want to refresh them after wiping, just like I re-set the local flow contexts.

Is it possible to simulate the deploy command? Deploy seems to automatically cause mqtt in to disconnect and reconnect.

I also would not mind a way of simply disconnecting and reconnecting on specific mqtt in node, if that were possible.

that is the sledgehammer approach.

Ok, but you get another yuk from me :wink:

Read the built in help for the MQTT node. You can send it a msg with action of "disconnect" and "connect" - that will cause MQTT to send out its retained subs again.

PS, this is really the wrong approach! but hey ho.

If you know of a better way, then I am happy to try it.

But I need to wipe all flow contexts and I need to refresh the ones originating from the mqtt in node afterwards.

:point_down:

Not sure it matters how many times I try to guide you, you almost always take the other path :man_shrugging:

1 Like

That approach is not feasible because I set a lot of flow contexts from incoming messages. So I cannot "store" them in one place.
Maybe 20 are defined in a node locally, all others are created from message properties.

But simlply subscribing to the topic again whenever I manually delete seems to work nicely.

Sure you can.

chrome_wRl3s7hv6d

[{"id":"21bbc89991e7877d","type":"inject","z":"758849023b96f626","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sm/test/retained/topic1","payload":"value 1","payloadType":"str","x":380,"y":940,"wires":[["6842d4a64b3bc3a2"]]},{"id":"88718eb71fa8025f","type":"inject","z":"758849023b96f626","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sm/test/retained/topic2","payload":"value 2","payloadType":"str","x":380,"y":980,"wires":[["6842d4a64b3bc3a2"]]},{"id":"27a6090f5a827dd5","type":"inject","z":"758849023b96f626","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sm/test/retained/topic3","payload":"value 3","payloadType":"str","x":380,"y":1020,"wires":[["6842d4a64b3bc3a2"]]},{"id":"6842d4a64b3bc3a2","type":"mqtt out","z":"758849023b96f626","name":"","topic":"","qos":"","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"0f2cd33b0937d5eb","x":650,"y":940,"wires":[]},{"id":"b942f4b394f8b965","type":"mqtt in","z":"758849023b96f626","name":"","topic":"sm/test/retained/#","qos":"2","datatype":"auto-detect","broker":"0f2cd33b0937d5eb","nl":false,"rap":true,"rh":0,"inputs":0,"x":470,"y":1100,"wires":[["f18a39d2564e76fb"]]},{"id":"f18a39d2564e76fb","type":"change","z":"758849023b96f626","name":"add to object","rules":[{"t":"set","p":"retainedTopics[msg.topic]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":1100,"wires":[[]]},{"id":"0f2cd33b0937d5eb","type":"mqtt-broker","name":"","broker":"test.mosquitto.org","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"5","keepalive":"60","cleansession":true,"autoUnsubscribe":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]

Anti pattern.