Feature Request: onDeploy callback

Let me preface this by saying that I haven't found any other way to solve this problem, so if anyone has any ideas please let me know!

For my Insteon device configuration nodes, I have run into a situation where the only way I can figure out how to reliably keep NR config node settings in sync with the physical hardware settings is to programmatically trigger the update and deploy buttons with my own button. This totally not the right way to do it.

This would not be necessary if there was an onDeploy callback that allowed me to write a block of client code for my config node that got executed when the user clicks the deploy button. This code block also needs to have the ability to throw an error that prevents the node's config from being written.

Some details of how the callback would be used in my node:

  • User opens the device node config panel for a motion sensor (or any device, but motion sensor is a good example because its battery powered and not listening unless the user wakes it up)
  • Changes are made to to the sensors settings (motion timeout duration for example)
  • User clicks update to close the config panel
  • User deploys
  • onDeploy callback is fired
  • callback issues ajax request to update the sensor

Now one of two things happens:

  • Insteon library was able to write the new settings to the device
  • Settings are re-read from the device (to verify) and sent back to the client
  • Client writes verified settings to the config
  • NR deploys and the flows.json file is written

Or:

  • Insteon library times out because the motion sensor is not reachable
  • ajax call reports failure, deployment of the config node is aborted (other nodes that succeed could deploy)

And for what it's worth, here's how I have worked around it by calling update and deploy

And here's a short video of the node in action with the above work around implemented.

2 Likes

If I"m reading that right, you mean you automatically deploy a users flows whenever they close the edit dialog for your node?

If so, that is really not acceptable. It is not for you to decide when the flows should be deployed or not.

Nor should a node be able to block a deploy from happening or not. For example, if you motion sensor wasn't currently online and you needed to make a critical fix to another part of your flow. The only option would be to disable all of your nodes first, deploy the fix and then figure out how to get all of the sensors back online at the right time so you could redeploy with the nodes active.

For your scenario, I would approach it like this:

  1. the config node contains the desired settings
  2. when it is deployed it attempts to update the device's settings/verify the existing settings match.
  3. if the node can't reach the device, have it periodically retry until it comes online.
  4. set the node status of your nodes to indicate what the current state is. For example: "pending verification" state and only update once it had successfully updated the device - the ensures the user is aware that the node has note yet confirmed the settings and they need to wake up the devices.

Another option would be a custom admin endpoint that you can trigger via a button in the node's edit dialog to update the device/verify the settings. Personally, I'd find it more convenient to be able to deploy the flows and reach eventual consistency as the devices wake up.

If I"m reading that right, you mean you automatically deploy a users flows whenever they close the edit dialog for your node?

No, that's not what I'm doing - will explain below.

Another option would be a custom admin endpoint that you can trigger via a button in the node's edit dialog to update the device/verify the settings.

That's what I've done. I have my own button in the config node's edit window which does an ajax call to an admin end point to attempt to write to the hardware.

Now for the problem: If the device write succeeds and the user closes the browser window without deploying, the physical device settings will no longer be in sync with the NR config node. Having an onDeploy callback would allow me to get rid of my custom button and instead trigger my node's write to device logic when the user deploys.

To work around this, I have made it so when the user clicks my custom button, they are also deploying the node - You can see it in the video I shared. The button the user clicks is Deploy & Write Changes to Device to make it as obvious as possible that writing to the device will also deploy NR.

For your scenario, I would approach it like this:

  1. the config node contains the desired settings
  2. when it is deployed it attempts to update the device's settings/verify the existing settings match.

Step 2 has to be done in the node's registerType in the JS file, correct?

  1. if the node can't reach the device, have it periodically retry until it comes online.
  2. set the node status of your nodes to indicate what the current state is. For example: "pending verification" state and only update once it had successfully updated the device - the ensures the user is aware that the node has note yet confirmed the settings and they need to wake up the devices.

You're describing what I tried first.

The first problem is that battery operated Insteon devices will not be reachable until a person physically presses and holds the device's set button for X seconds. The second problem is that the downloading the links database from an Insteon device is time consuming (I've seen it take up to 40 seconds).

I have nearly 100 insteon devices, 20% of which are battery powered - so this is the use case I am testing against.

When you do a full deploy in NR, the registerType for each node is run to rebuild it - so we cannot put any insteon query code in the node's registerType constructor. Instead, I am getting all of the device's data one time when the user first adds it to the environment and then caching all of those settings in the device's config node.

That part is clean and works well. The heartburn comes with trying to deal with someone closing without deploying.

I'm not sure I fully understand the issue but based on the stated need you could, perhaps, use the 'Inject' node with the correct option set ('Inject once...')?

Help text: " The Inject node can initiate a flow with a specific payload value. The default payload is a timestamp of the current time in millisecs since January 1st, 1970.

The node also supports injecting strings, numbers, booleans, JavaScript objects, or flow/global context values.

By default, the node is triggered manually by clicking on its button within the editor. It can also be set to inject at regular intervals or according to a schedule.

It can also be configured to inject once each time the flows are started."

Perhaps some experimentation on that needed?
Cheers,
Paul

No, the inject node is not appropriate for this. I am talking about config node development, it doesn't use or rely on a flow. We are using the configuration node as a UI to manage settings of a physical device.

Having an onDeploy callback would allow me to get rid of my custom button and instead trigger my node's write to device logic when the user deploys.

These functions don't help ?

  • oneditprepare : (function) called when the edit dialog is being built. See custom edit behaviour.
  • oneditsave : (function) called when the edit dialog is okayed. See custom edit behaviour.
  • oneditcancel : (function) called when the edit dialog is cancelled. See custom edit behaviour.
  • oneditdelete : (function) called when the delete button in a configuration node’s edit dialog is pressed. See custom edit behaviour.

"Writing" something to a device while you are configuring a node is a weird approach.
Don't you have a hub ? Those are usually used to maintain states.

These functions don't help ?

Well - no - because none of those callbacks are mutually inclusive with deploy.

Don't you have a hub ? Those are usually used to maintain states.

The project I am working on is to make Node-RED an Insteon hub. It means one less device, less complexity for integration, and far more powerful than the hub is (or any other Insteon home automation controller for that matter).

Users will be able to combine our insteon nodes with the homekit and/or google home nodes, plus do whatever automation they want with NR flows.

"Writing" something to a device while you are configuring a node is a weird approach.

Maybe... but I think I'm not the first one to encounter this problem. There are other nodes out there that are struggling with a similar problem and have resorted to writing to external cache/databases instead of using NR itself.

The problem - and the reason I do not want to have a separate own config storage - is that I want all of the config to be portable and backed up with the NR flow itself. You should be able to export / import between docker containers for example. Another important thing is that if an Insteon hardware device fails you should be able to easily replace it with a new device (which means writing the cached config stored in NR onto the new device).

Well, all I'll say is that it does seem sensible to have an event that is triggered on Deploy.