Sending messages inside callback functions

Github is https://github.com/Bobo-amg/Node-Red-Daily-Scheduler

Appreciate any assistance.

Cheers

I can have a look this evening. Can you commit a small test flow as well?

Nothing needed except Inject on one side and Debug on the other. Then edit the local time and add a description. Deploy and Inject.

Okay, that's simple then. I thought you needed some kind of schedule configuration for the node. :grin:

Well I did design it to accept input from something like the ui form node, yes. So the real use case (for me) is using that (via msg.alarm_date). But for testing (and learning) I incorporated the same into the editor. It's possible there is a problem there somewhere.

It is also possible that I didn't clone the msg correctly in my attempts, although I did try several different code methods.

By editor you mean that you enter the values as node properties in the UI?

Because you set editor or inputmsg depending on whether the message had the alarm_date properties or not.

I can look at it this evening (CET) in detail... I think I will need to restructure and clean that code up a bit. :see_no_evil::grinning:

Just out of curiosity... I haven't used any of the existing scheduler nodes yet, but what is this node supposed to do differently? :grinning:

Yes, in the node's editor.

Go for it, although isn't javascript meant to be "all over the place"? Coming from the old days, this stuff hurts me :stuck_out_tongue_winking_eye:

Also bear in mind that I have stripped some code out and added some "redundant" code in, in an attempt to find the issue. :nerd_face:

Well ... :thinking:

I started building this a long time ago (then lost my allocated play time to continue it), and since then a couple of other scheduling nodes have come to market. I continued with this one because it was as much a learning experience as it was solving an issue for me.

It is however only meant to be a day based scheduler (for testing right now it is MINUTE based though- you do not have to wait days for events to fire :rofl:), nothing else. To that end I added a few things like monthly recurring alarms, early reminder alarms etc.

Just wondering if you had a chance to take a look yet?

I have already forked it, set up a dev environment and started a simple flow. But some other thing came up, I think I can continue next week. :see_no_evil:

Np. Thanks.

Lost track of the thread at the end there. In case it is of help, here is a basic test node that I use to play with and that shows how I'm now handling the send() function so that it works correctly with pre and post v1.


'use strict'

/** Dummy logging 
 * @type {Object.<string, function>} */
var dummyLog = {
    fatal: function(){}, // fatal - only those errors which make the application unusable should be recorded
    error: function(){}, // error - record errors which are deemed fatal for a particular request + fatal errors
    warn: function(){},  // warn - record problems which are non fatal + errors + fatal errors
    info: function(){},  // info - record information about the general running of the application + warn + error + fatal errors
    debug: function(){}, // debug - record information which is more verbose than info + info + warn + error + fatal errors
    trace: function(){}, // trace - record very detailed logging + debug + info + warn + error + fatal errors
}
var log = dummyLog // reset to RED.log or anything else you fancy at any point

const moduleName = 'nrtest'

/** Export the function that defines the node */
module.exports = function(RED) {
    // NB: entries in settings.js are read-only and shouldn't be read using RED.settings.get, that is only for settings that can change in-flight.
    //     see Node-RED issue #1543.

    /*  RED.events.on('nodes-started',function() {
            console.log('****** All nodes have started ******')
        })
        RED.events.on('nodes-stopped',function() {
            console.log('****** All nodes have stopped ******')
        }) 
    */

    //#region ----- Constants (& logging) for standard setup ----- //

    /** Folder containing settings.js, installed nodes, etc. @constant {string} userDir */
    //userDir = RED.settings.userDir
    
    /** Root URL path for http-in/out and uibuilder nodes @constant {string} httpNodeRoot */
    //const httpNodeRoot = RED.settings.httpNodeRoot

    //#region ----- back-end debugging ----- //
    log = RED.log
    log.trace('[NRTEST:Module] ----------------- module started -----------------')
    //#endregion ----- back-end debugging ----- //

    //const app = RED.httpNode // || RED.httpAdmin

    //#endregion -------- Constants -------- //

    /** Run the node instance - called from registerType()
     * @param {Object} config The configuration object passed from the Admin interface (see the matching HTML file)
     */
    function nodeGo(config) {
        // Create the node
        RED.nodes.createNode(this, config)

        /** A copy of 'this' object in case we need it in context of callbacks of other functions. @constant {Object} node */
        const node = this
        log.trace('[NRTEST:nodeGo] = Keys: this, config =', {'this': Object.keys(node), 'config': Object.keys(config)})

        //var context = this.context().flow
        console.log('[NRTEST:nodeGo] ', {'this': node, 'config': config})

        //#region ----- Create local copies of the node configuration (as defined in the .html file) ----- //
        // NB: node.id and node.type are also available
        node.name          = config.name  || ''
        node.topic         = config.topic || ''
        //#endregion ----- Local node config copy ----- //

        /** Handler function for node input events (when a node instance receives a msg)
         * @see https://nodered.org/blog/2019/09/20/node-done 
         * @param {Object} msg The msg object received.
         * @param {function} send Per msg send function, node-red v1+
         * @param {function} done Per msg finish function, node-red v1+
         **/
        function nodeInputHandler(msg, send, done) {

            // If this is pre-1.0, 'send' will be undefined, so fallback to node.send
            send = send || function() { node.send.apply(node,arguments) }
            // If this is pre-1.0, 'done' will be undefined, so fallback to dummy function
            done = done || function() { if (arguments.length>0) node.error.apply(node,arguments) }

        } // -- end of msg received processing -- //

        // Process inbound messages
        node.on('input', nodeInputHandler)

        // Do something when Node-RED is closing down
        // which includes when this node instance is redeployed
        node.on('close', function(removed,done) {
            log.trace(`[NRTEST:nodeGo:onClose] ${removed?'Node Removed':'Node (re)deployed'}`)

            node.removeListener('input', nodeInputHandler)

            done()
        })

    } // ---- End of nodeGo (initialised node instance) ---- //

    /** Register the node by name. This must be called before overriding any of the
     *  Node functions. */
    RED.nodes.registerType(moduleName, nodeGo)

} // ==== End of module.exports ==== // 

// EOF

I have refactored the code to make it simpler to debug. It sits in the updated branch. Also opened an issue.
If anyone has the time to take a look I would be most grateful.