Dictionary object in Context

Hi there,

I connected my flow to my paradox alarm system.

It sends events when a door or window is opened or closed. I would like to keep the states of all sensors in a dictionary that is available for all my flows.

I have an incoming message that contains the sensor name and the state ("open" or "closed"). I would like a dictionary like this:

{"door1": "open", "door2: "closed", "window1": "closed"} etc.

I could not find a way to set the global context to contain an aggregate object, like a dictionary.

This code keeps the last sensor data only.
sensor = msg.payload.sensor;
state = msg.payload.state;
global.set('paradox_states', [{value:sensor, key:state}]);

I suspect the problem is that context is evaluated real time and I struggle passing sensor name to the paradox_states object.

Any suggestions?

Thanks,
Zoltan

let sensor = msg.payload.sensor;
let state = msg.payload.state;
let dic = global.get('paradox_states') || {};
dic[sensor]=state;
global.set('paradox_states', dic);

1 Like

Also consider whether you really need global variables. If you are using MQTT then saving the state of the real world in persistent topics in MQTT can be a better way of doing it. Then you have the advantage that whenever the door is opened you will get a notification in any flow that has subscribed to the topic home/door1/state for example.

1 Like

Thanks, Steve! I'd swear I tried exactly your solution, but for some reason did not work for me. Now, everything is OK. This is exactly was I was going for.

BR,
Zoltán

Hi Colin, thanks for your suggestion.

There are cases where I intentionally use MQTT persistence, but IMHO this is not the case for me now.

E.g. I developed a Grafana custom MQTT panel for an intelligent building project for a winery. The interactive panel displayed the state of lamp switches. I used the MQTT Retain flag intentionally, because that was an architecture where services talked to each other via MQTT messages.

However, in this case I need

  • an easily searchable array (hence the dictionary),
  • that is available in all my flows,
  • that would make it possible to poll the states by using an expression in a function node.

The last point is hard to meet with MQTT. If I used MQTT in this case, then retrieving the state of a sensor would be split into two: sending and receiving MQTT messages. But that would split my flow into two branches, which I would not like.

Thanks for the idea, anyway.

BR,
Zoltán

If you feed the mqtt message into the function node (possibly via a Join node to join it with other data) then the latest value will always be available. Also you can use it to trigger the function node when it changes (if that is a requirement). Either way there is no need to poll. The same technique allows the other points to be addressed too.

I am not saying that MQTT is always the best solution, it is a matter of weighing up the pros and cons each time.

1 Like

I see what you mean.

  • My flow sends the MQTT message to poll the sensor state.
  • The MQTT response immediately arrives, due to persistence.
  • The Join node holds the status until an another message arrives and tells that the sensor status is needed. --> This is the point I missed.

Good idea.

Thanks!
Z

What sort of sensor are you using that needs to be polled via mqtt?

Paradox EVO 192 alarm system. It has an IP interface and the PAI GH repo converts all alarm events to MQTT messages.

So the door/window/infra sensor events are available as MQTT messages. This is still event driven.
But I need to use the states in my expressions. That is state driven.
Therefore I need to keep the last state somewhere, that can be accessed by a JS expression very easily. And that's a dictionary IMHO.

1 Like

Understood, as I said it is a matter of deciding which is best for any particular application, and personal preference comes into it too.

1 Like

My first use case is a push notification message when a window is open for for more than 10 minutes. (An average request from my wife.) But do be too noisy so send the notification only if the windows hasn't been shut before the 10 minutes passed. That's the catch: I need the current state if the window.

You could feed the mqtt input with the window state into a Trigger node set to Send Nothing, then after 10 minutes send the Latest Message, and with Extend Delay set. Feed the output through a Switch node to only pass window open messages and use that to trigger the notification.

1 Like

That's great too. Very simple.

I tried it too, but I set the "Reset the trigger if msg.payload equals" to "close" in the Trigger node. That way the alert will be suppressed if the door/window is closed before the time-out.

Thank you guys for all the valuable comments. I appreciate it. Now I have 3 completely different solutions :slight_smile:

I learnt a lot.

Happy coding,
Z

1 Like

You are right, that is much better, then you don't need the Switch node either and you can construct whatever message you need to be sent in the Trigger to go directly to wherever it has to go.

1 Like

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