UNPKG

@maddytp/node-red-dashboard-2-ui-reef

Version:

Set of UI nodes for aquarium automation based on @flowfuse/node-red-dashboard

122 lines (117 loc) 5.09 kB
module.exports = function (RED) { function UIProbe (config) { RED.nodes.createNode(this, config) const node = this const group = RED.nodes.getNode(config.group) const base = group.getBase() if (typeof config.decimal !== 'undefined') { config.decimal = parseFloat(config.decimal) } if (typeof config.minin !== 'undefined') { config.minin = parseFloat(config.minin) } if (typeof config.minout !== 'undefined') { config.minout = parseFloat(config.minout) } if (typeof config.maxin !== 'undefined') { config.maxin = parseFloat(config.maxin) } if (typeof config.maxout !== 'undefined') { config.maxout = parseFloat(config.maxout) } function hasProperty (obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop) } function toFixedNumber (num, digits, base) { const pow = Math.pow(base ?? 10, digits) return Math.round(num * pow) / pow } const evts = { onChange: true, beforeSend: function (msg) { let err = false const p = msg.payload if (Array.isArray(p)) { msg._datapoint = p.map((point) => { return addToChart(point) }) } else { msg._datapoint = addToChart(p) } function addToChart (p) { const datapoint = {} if (typeof p === 'number') { datapoint.x = (new Date()).getTime() datapoint.y = p } else if (typeof p === 'object') { datapoint.x = hasProperty(p, 'x') ? p.x : (new Date()).getTime() datapoint.y = (typeof p.y === 'number') ? p.y : 'ERR' } else { datapoint.y = 'ERR' } if (datapoint.y === 'ERR') { err = true return datapoint } if (config.scale) { if (datapoint.y <= config.minin) { datapoint.y = config.minin } if (datapoint.y >= config.maxin) { datapoint.y = config.maxin } datapoint.y = (((datapoint.y - config.minin) / (config.maxin - config.minin)) * (config.maxout - config.minout)) + config.minout } datapoint.y = toFixedNumber(datapoint.y, config.decimal, 10) return datapoint } if (err) { node.error('Invalid payload!', msg) } return msg }, onInput: function (msg, send, done) { if (!base.stores.data.get(node.id)) { base.stores.data.save(base, node, []) } if (Array.isArray(msg.payload) && !msg.payload.length) { base.stores.data.save(base, node, []) } else { if (!Array.isArray(msg.payload)) { base.stores.data.append(base, node, { ...msg }) } else { msg.payload.forEach((p, i) => { const payload = JSON.parse(JSON.stringify(p)) const d = msg._datapoint ? msg._datapoint[i] : null const m = { ...msg, payload, _datapoint: d } base.stores.data.append(base, node, m) }) } if (config.removeOlder && config.removeOlderUnit) { const removeOlder = parseFloat(config.removeOlder) const removeOlderUnit = parseFloat(config.removeOlderUnit) const ago = (removeOlder * removeOlderUnit) * 1000 const cutoff = (new Date()).getTime() - ago const _msg = base.stores.data.get(node.id).filter((msg) => { let timestamp = msg._datapoint.x if (typeof (msg._datapoint.x) === 'string') { timestamp = (new Date(msg._datapoint.x)).getTime() } return timestamp > cutoff }) base.stores.data.save(base, node, _msg) } } send(msg) } } if (group) { group.register(node, config, evts) } else { node.error('No group configured') } } RED.nodes.registerType('ui-probe', UIProbe) }