How can I 'delete' via the Admin API Methods?

#1

Hi,

I am using the Admin API Methods to get information about the configuration of a node. Specifically which pins are in use on some digital outputs.

In the .js file:

RED.httpAdmin.get('/Digital-output/node-input-pin', RED.auth.needsPermission('Digital-output.read'), function(req,res) {
    res.json(pinsInUse);
});

But this JSON like string, is only updating when i hit 'Deploy'. Is there a way to update the string, when I hit 'Okay' button in node-red? I know the 'oneditsave' where I could implement a function to do so, but I am out of ideas how I should do it?

Any good ideas? :slight_smile:

#2

You have access to jQuery so you can attach an event to any on-screen object. In the oneditprepare section, create the event handler so that when the button is hit, the API is called.

If you want an example of something similar, check out the adminui-editor branch of node-red-contrib-uibuilder. This has a button that triggers an API call to get the contents of a file and display it in an editor component.

#3

Thanks.

But the API only allows me to use the GET function. With this, I cannot update the JSON like string. Do you get me?

In what module does the code for the 'Deploy' button live? Or is there a way to read all nodes configurations, which are not yet deployed?

#4

Hi @Simo219h

You have added a custom GET handler to retrieve the current value.

You could add a custom POST handler to allow you send an updated value back to the server:

RED.httpAdmin.post('/Digital-output/node-input-pin', RED.auth.needsPermission('Digital-output.write'), function(req,res) {
    // do something with req.body to update pinsInUse
});

However, this does pose some other issues you'll face.

Consider this scenario:

  1. a user edits the node and clicks okay
  2. your code sends the POST to the runtime to update pinsInUse
  3. the user deletes the node
  4. pinsInUse is now out of date

To handle that, you'd also need to add an oneditdelete function to do the POST so the runtime stays in sync.

You would also want to reset pinsInUse whenever a deploy happens as that is the true system of record for what pins are actually in use.

1 Like
#5

Thank you very much. I think this is what I am looking for!
I will try it out now, and let you know if I can get it to work the right way.

#6

I got it all working now. Only facing one problem...

When I hit the deploy button sometimes it takes up to 40 seconds to respond, and sometimes it comes immediately.

Any clues what that could be?

#7

It can be caused by a node taking a while to stop for some reason.

If you enable the "trace" level of logging in your settings file, you may get a bit more of a clue

#8

I have tried that, nothing suspicious there.
Can it be something with POST commands I am doing? I'have noticed that the page the POST sends to is not responding at times between I hit the 'Okay' button or 'Delete' button.

        oneditprepare: function() {
        //Get the current pin value
        var i;
        pinNowValue = $("#node-input-pin").val();

        //Get pins already configured in flow
        $.getJSON('Digital-output/node-input-pin', function(data) {
            pinsInUse = data || {};
        });
        
        //Hide already used pins
        if(Object.keys(pinsInUse).length == 0) {
                console.log("This node is new and not configured!");
        }
        else {
            pinProperties = Object.keys(pinsInUse);
            console.log("Already used pins:");
            $("#node-input-pin option[value='"+pinNowValue+"']").show();
            for(i=0; i < pinProperties.length; i++) {
                $("#node-input-pin option[value='"+pinProperties[i]+"']").hide();  
                console.log(pinProperties[i]);
            }    
        }
    },
    oneditsave: function() {
        pinNewValue = $("#node-input-pin").val();
        
        //Delete the old pin value, and update it to new
        if(pinNewValue) {
            if(pinNowValue) {
                delete pinsInUse[pinNowValue];
            }
            pinsInUse[pinNewValue] = "in use";
            $.post( "Digital-output/node-input-pin", pinsInUse);
        }      
    },
    oneditdelete: function() {
        //Delete the current pin value
        if(pinNowValue) {
            delete pinsInUse[pinNowValue]; 
            $.post( "Digital-output/node-input-pin", pinsInUse);
        }
    }

Here is the log from node-red with 'trace' enabled. This is what happens, when I hit 'deploy' and it takes about a minute for deployment.

30 Jan 12:58:25 - [info] Server now running at http://127.0.0.1:1880/
30 Jan 13:01:41 - [debug] saved flow revision: 9baf826f7f020845f4fa3140c47448e2
30 Jan 13:01:41 - [info] Stopping flows
30 Jan 13:01:41 - [debug] red/nodes/flows.stop : stopping flow : global
30 Jan 13:01:41 - [debug] red/nodes/flows.stop : stopping flow : 6e97389f.ee1f28
30 Jan 13:01:41 - [trace] Stopping node Digital-output:6029074e.649318 removed
30 Jan 13:01:41 - [trace] Stopping node Digital-output:66c1cbd0.9d1d44 removed
30 Jan 13:01:41 - [trace] Stopping node Digital-output:b32e88c5.a2d9a8 removed
30 Jan 13:01:41 - [trace] Stopping node Digital-output:7a270a2c.4a58a4 removed
30 Jan 13:01:41 - [trace] Stopped node Digital-output:6029074e.649318 (38ms)
30 Jan 13:01:41 - [trace] Stopped node Digital-output:66c1cbd0.9d1d44 (26ms)
30 Jan 13:01:41 - [trace] Stopped node Digital-output:b32e88c5.a2d9a8 (22ms)
30 Jan 13:01:41 - [trace] Stopped node Digital-output:7a270a2c.4a58a4 (21ms)
30 Jan 13:01:41 - [info] Stopped flows
30 Jan 13:01:41 - [info] Starting flows
30 Jan 13:01:41 - [debug] red/nodes/flows.start : starting flow : global
30 Jan 13:01:41 - [debug] red/nodes/flows.start : starting flow : 6e97389f.ee1f28
30 Jan 13:01:41 - [trace] runtime event: {"id":"runtime-state","retain":true}
30 Jan 13:01:41 - [info] Started flows
30 Jan 13:01:41 - [trace] runtime event: {"id":"runtime-deploy","payload":{"revision":"9baf826f7f020845f4fa3140c47448e2"},"retain":true}

#9

Problem solved. I forgot to send a response back from the POST handler...

1 Like