Copprhead - Notifications in Node-RED: I'm play...
Notifications in Node-RED: I'm playing with SK/Node-RED to control an external alarm buzzer. An alarm is triggered by a notification for a certain key. For that I'm using the 'notification' node and it works fine for changes.
But when the key/notification goes into alarm state while Node-RED is not "there" (yet), and then Node-RED comes up, it won't be notified of the alarm since the notifications are sent only when the state changes.
Ideally, the notification node would get the current state once when it starts up, and then the changes when they happen. This is not a big deal for keys that update every second (e.g. depth), but it is a problem for keys that change only very occasionally. (Same goes for the 'subscribe' node I think.)
Is there something I'm missing? (I thought maybe I can query the current state on initialization, but I don't see a way how.)
33 Replies
You can setup a flow to check the value a startup. But yeah, the notification node should have that ability (like the subscribe node does)
How would I do that?
So that’s an inject node that’s set to fire once at startup, then a function that gets the notification state and passes it on.
Great, thank you. That works. Didn't know you had access to 'app', that's nice.
Can I use wildcards in app.getSelfPath() to get an array? For example for checking if any notification is in alarm state?
no
Well…
You can getSelfPath(‘notifications’)
Then you can traverse them all.
Just tried:
let notifs = app.getSelfPath('notifications')
node.warn(notifs.length)
And that gives me 'undefined'.
That’s going to be an object, not an array
oh yeah
Yes it works. But it's kinda hard to parse through all that to find the one (who knows how deep) that has alarm state and then go back up to get the key...
Not simple, but definitely doable.
Object.entries
and Object.keys
are handy for traversing nested objects. There are helpers in lodash if you already know the path to the desired valueThank you. Yes, doable. But it would always mean that I end up polling the state, instead of subscribing, right? So the generic "any alarm" approach would be a bit ugly.
Might be better after all to explicitly define the keys I want to monitor for alarms and use notification (with initial polling).
here's a function that traverses
notifications
and outputs messages for each notification
Cool thank you! I added "&& sub == 'alarm'" and it does what I need 🙂
So I'll just run this every 1s inside an endless loop, or do you have a better suggestion? If it comes out empty, I'll stop the buzzer, if it has a result, I'll start it. Should be ok for now, can still refine later.
I would just run that once at startup. And use the notification node to get any changes
yeah but then I'd have know exactly which keys to check
I think wildcards work with that node
Oh yes it does. Good!
Hmm, next problem. To turn off the alarm I used to wait for the notification for key xyz with state=normal. The equivalent with * would turn off the alarm when the first key goes to normal, and there could be other keys still in alarm, but my buzzer would turn off.
You would need to keep some state. Like keep a count of the number of alarms. When it reaches zero, turn off the buzzer
I guess that could be done. Not sure how reliable though.
Performance-wise, is it very bad to poll with the function above vs. using notifications?
It’s definitely much worse performance wise, but if your might not even notice it.
I don’t see any reason keeping a count would not be reliable
ok will try later, gotta go now. Thanks!
Is there no way a notification can get lost? That would screw up the counter.
There's another problem: I'm using the notification node now with * and state=alarm for alarming/increasing the counter, and with * and state=normal for cancelling the alarm/decreasing the counter. This generally works when I change my key into the alarm zone and back for testing. But sometimes I'm getting notifications for every "normal" state key (20+), even though these haven't been in alarm before, neither have subscribed to them in any way. Why is that? (Needless to say the counter is not going to work like that.)
These "normal" notifications are for propulsion.* keys. And they only come when I have a logfile data connection active. When I recorded this data, I had an engine->N2K interface connected and the engine running. But the values were not in alarm, neither are they now shown as alarm (ever), only normal.
Oh, right, didn’t think about that.
It could happen the other way also.
Let me see how I do this in the fusion plugin…
Ok, I use a Map to store exceptions that are not in normal
See the get_delta function https://github.com/sbender9/signalk-fusion-stereo/blob/master/index.js
GitHub
signalk-fusion-stereo/index.js at master · sbender9/signalk-fusion-...
signalk-server-node plugin to control a Fusion stereo - sbender9/signalk-fusion-stereo
Ok.
Another question... I'm letting a led blink with a trigger. First message: turn led on, second message after 250ms: turn led off -> delay(250ms) ->start over. The led starts blinking regularly, but every now and then it "stutters", either the light phase or the dark phase are a bit too long. Is there anything I can do about it?
Sorry, don’t know
Polling is a pretty common pattern for checking the state for alarms. Grafana uses the same pattern for all data sources. It’s more process intensive but a lot more reliable
Signalk deltas are extremely reliable, there’s no reason to do polling that I can think of.
(except for this case where he needs to get the current state when he starts up)
The other way that can be reliable is putting them in a message queue via a plugin. The subscriber would be required to process and signal to remove from the queue which would still stay with a pub/sub system. But a different runtime requires some polling mechanism
In this case, node-red is running inside the server process. There’s no reason to go through all that.
If the subscribe and notification nodes would send the current state when started, everything would be fine. The updates are working well and unnecessary (too many) updates are normally not a problem.
The subscribe node does send the current state when started
I need to add those same options the subscribe node has to the notification node
Not sending anything by itself here, only when the key is updated.
I added a subscribe node with my path, attached a debug, deployed. Got nothing. When I changed the value in data fiddler, got the change shown. Or the same value if not changed but resent. But on deploying I'm not getting anything from subscribe.
What do you have "Mode" set to for the subscribe node?>
hmm, yep, something is broken. that's not working anymore.