@totallyinformation/node-red-contrib-drayton-wiser
Version:
Easily create data-driven web UI's for Node-RED using any (or no) front-end library.
134 lines (107 loc) • 5.37 kB
JavaScript
/** Listens for an event based on a msg.topic and outputs a copy of the msg
* Destructured to make for easier and more consistent logic.
*
* Copyright (c) 2022 Julian Knight (Totally Information)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** --- Type Defs ---
* @typedef {import('../typedefs.js').runtimeRED} runtimeRED
* @typedef {import('../typedefs.js').runtimeNodeConfig} runtimeNodeConfig
* @typedef {import('../typedefs.js').runtimeNode} runtimeNode
* @typedef {import('../typedefs.js').wiserListenNode1} wiserListenNodeExt
* @typedef {runtimeNode & wiserListenNodeExt} wiserListenNode
* @typedef {import('../typedefs.js').wiserListenNodeConfig1} wiserListenNodeConfigExt
* @typedef {runtimeNodeConfig & wiserListenNodeConfigExt} wiserListenNodeConfig
* @typedef {import('../typedefs.js').wiserListenModVar1} wiserListenModVar */
//#region ----- Module level variables ---- //
const util = require('util')
const tiEvents = require('@totallyinformation/ti-common-event-handler')
// tiEvents.onAny(function(event, value) {
// if ( event === 'newListener')
// console.log('Wiser Listen :: TI EVENT: ', event, value);
// else
// console.log('Wiser Listen :: TI EVENT: ', event) //, value);
// })
/** Main (module) variables - acts as a configuration object
* that can easily be passed around.
*/
const mod = {
/** @type {runtimeRED} Reference to the master RED instance */
RED: undefined,
/** @type {string} Custom Node Name - has to match with html file and package.json `red` section */
nodeName: 'wiser-listen',
}
//#endregion ----- Module level variables ---- //
//#region ----- Module-level support functions ----- //
/** 2) This is run when an actual instance of our node is committed to a flow
* @param {wiserListenNodeConfig} config The Node-RED node instance config object
* @this {wiserListenNode}
*/
function nodeInstance(config) {
// As a module-level named function, it will inherit `mod` and other module-level variables
// If you need it - which you will here - or just use mod.RED if you prefer:
const RED = mod.RED
// Create the node instance - `this` can only be referenced AFTER here
RED.nodes.createNode(this, config)
// Transfer config items from the Editor panel to the runtime
this.name = config.name
this.eventname = config.eventname
// Allow for and convert MQTT-style wildcards
this.eventname = 'wiser/' + this.eventname.replace(/#/g, '**').replace(/\+/g, '*')
const eventName = this.eventname
const node = this
function sender(data) {
// console.log(`[wiser:listen:sender] TI Event Triggered: '${this.event}`)
//console.log(`TI Event Triggered: '${this.event} :: \n${util.inspect(data, {depth:2,colors: true,showProxy: true,compact: false,})}`)
node.send({
topic: this.event,
payload: data,
})
}
// Create new listener for the given topic, record it so that it can be removed on close
tiEvents.on(eventName, sender)
// console.log(`>> nodeInstance ${this.id} :: event names with listeners >>`, tiEvents.eventNames())
/** Put things here if you need to do anything when a node instance is removed
* Or if Node-RED is shutting down.
* Note the use of an arrow function, ensures that the function keeps the
* same `this` context and so has access to all of the node instance properties.
*/
this.on('close', (removed, done) => {
// Remove this event listener
tiEvents.removeListener(eventName, sender)
// console.log(`>> on.close ${this.id} :: event names with listeners >>`, tiEvents.eventNames())
done()
})
/** Properties of `this`
* Methods: updateWires(wires), context(), on(event,callback), emit(event,...args), removeListener(name,listener), removeAllListeners(name), close(removed)
* send(msg), receive(msg), log(msg), warn(msg), error(logMessage,msg), debug(msg), trace(msg), metric(eventname, msg, metricValue), status(status)
* Other: credentials, id, type, z, wires, x, y
* + any props added manually from config, typically at least name and topic
*/
}
//#endregion ----- Module-level support functions ----- //
/** 1) Complete module definition for our Node. This is where things actually start.
* @param {runtimeRED} RED The Node-RED runtime object
*/
function EventListen(RED) {
// As a module-level named function, it will inherit `mod` and other module-level variables
// Save a reference to the RED runtime for convenience
mod.RED = RED
// Register a new instance of the specified node type (2)
RED.nodes.registerType(mod.nodeName, nodeInstance)
}
// Export the module definition (1), this is consumed by Node-RED on startup.
module.exports = EventListen
//EOF