node-red-contrib-minelert-universal-io
Version:
Node-RED nodes for Universal IO Gateway and I/O Modules
84 lines (67 loc) • 2.67 kB
JavaScript
const mqtt = require('mqtt');
const { EventBus, logInfo } = require('@minelert-smartlink/common');
module.exports = function (RED) {
function GatewayNode(config) {
RED.nodes.createNode(this, config);
const node = this;
// Load config
const mqttHost = config.mqttHost || 'mqtt://localhost';
const sensorEventTopic = 'smartlink/sensors/+/event';
const ioChannelEventTopic = 'smartlink/io/+/+/channel/+';
// MQTT setup
const mqttClient = mqtt.connect(mqttHost);
// this.listeners = [];
// this.registerListener = (cb) => this.listeners.push(cb);
mqttClient.on('connect', () => {
node.log('MQTT connected');
mqttClient.subscribe(sensorEventTopic, (err) => {
if (err) node.error(`MQTT subscribe error: ${err.message}`);
else node.log(`Subscribed to MQTT topic: ${sensorEventTopic}`);
});
mqttClient.subscribe(ioChannelEventTopic, (err) => {
if (err) node.error(`MQTT subscribe error: ${err.message}`);
else node.log(`Subscribed to MQTT topic: ${ioChannelEventTopic}`);
});
});
mqttClient.on('message', (topic, message) => {
const payloadStr = message.toString();
try {
const payload = JSON.parse(payloadStr);
node.log(JSON.stringify(payload))
if (topic.startsWith("smartlink/sensors/")) {
const topicArr = topic.split('/')
const id = topicArr[2]
EventBus.emit('sensor-event', payload);
} else if (topic.startsWith("smartlink/io/")) {
const topicArr = topic.split('/')
const id = topicArr[2]
const ioType = topicArr[3]
const channel = Number(topicArr[5])
EventBus.emit('io-channel-event', {moduleId: id, ioType: ioType, channel: channel, value: payload.value});
}
} catch (err) {
node.error(`Invalid MQTT JSON: ${err.message}`);
}
});
mqttClient.on('error', (err) => {
node.error(`MQTT error: ${err.message}`);
});
// Send command over mqtt (from within Node-RED or EventBus)
function sendCommand(msg) {
const { topic, command } = msg
console.log(topic, command)
// node.log(`Sending ${msg.topic}: ${msg.command}`);
mqttClient.publish(topic, JSON.stringify(command))
}
node.sendCommand = sendCommand;
EventBus.on('send-command', sendCommand);
// Cleanup on node shutdown
node.on('close', (removed, done) => {
node.log('Closing Gateway node...');
EventBus.off("send-command", sendCommand);
if (mqttClient.connected) mqttClient.end();
done();
});
}
RED.nodes.registerType('gateway', GatewayNode);
};