diff --git a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html index bb76b33bc..009076cf9 100644 --- a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html +++ b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html @@ -249,6 +249,12 @@ +
+ +
@@ -483,17 +489,23 @@ tls: {type:"tls-config",required: false, label:RED._("node-red:mqtt.label.use-tls") }, clientid: {value:"", validate: function(v, opt) { - var ok = false; + let ok = true; if ($("#node-config-input-clientid").length) { // Currently editing the node - ok = $("#node-config-input-cleansession").is(":checked") || (v||"").length > 0; + let needClientId = !$("#node-config-input-cleansession").is(":checked") || !$("#node-config-input-autoUnsubscribe").is(":checked") + if (needClientId) { + ok = (v||"").length > 0; + } } else { - ok = (this.cleansession===undefined || this.cleansession) || (v||"").length > 0; + let needClientId = !(this.cleansession===undefined || this.cleansession) || this.autoUnsubscribe; + if (needClientId) { + ok = (v||"").length > 0; + } } - if (ok) { - return ok; + if (!ok) { + return RED._("node-red:mqtt.errors.invalid-client-id"); } - return RED._("node-red:mqtt.errors.invalid-client-id"); + return true; }}, autoConnect: {value: true}, usetls: {value: false}, @@ -505,6 +517,7 @@ label: RED._("node-red:mqtt.label.keepalive"), validate:RED.validators.number(false)}, cleansession: {value: true}, + autoUnsubscribe: {value: true}, birthTopic: {value:"", validate:validateMQTTPublishTopic}, birthQos: {value:"0"}, birthRetain: {value:"false"}, @@ -620,6 +633,10 @@ this.cleansession = true; $("#node-config-input-cleansession").prop("checked",true); } + if (typeof this.autoUnsubscribe === 'undefined') { + this.autoUnsubscribe = true; + $("#node-config-input-autoUnsubscribe").prop("checked",true); + } if (typeof this.usetls === 'undefined') { this.usetls = false; $("#node-config-input-usetls").prop("checked",false); @@ -635,6 +652,14 @@ if (typeof this.protocolVersion === 'undefined') { this.protocolVersion = 4; } + $("#node-config-input-cleansession").on("change", function() { + const useCleanSession = $("#node-config-input-cleansession").is(':checked'); + if(useCleanSession) { + $("div.form-row.mqtt-persistence").hide(); + } else { + $("div.form-row.mqtt-persistence").show(); + } + }); $("#node-config-input-protocolVersion").on("change", function() { var v5 = $("#node-config-input-protocolVersion").val() == "5"; if(v5) { diff --git a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js index 0a7ed6dfa..9e17463dd 100644 --- a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js +++ b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js @@ -482,6 +482,7 @@ module.exports = function(RED) { setIfHasProperty(opts, node, "protocolVersion", init); setIfHasProperty(opts, node, "keepalive", init); setIfHasProperty(opts, node, "cleansession", init); + setIfHasProperty(opts, node, "autoUnsubscribe", init); setIfHasProperty(opts, node, "topicAliasMaximum", init); setIfHasProperty(opts, node, "maximumPacketSize", init); setIfHasProperty(opts, node, "receiveMaximum", init); @@ -590,6 +591,9 @@ module.exports = function(RED) { if (typeof node.cleansession === 'undefined') { node.cleansession = true; } + if (typeof node.autoUnsubscribe === 'undefined') { + node.autoUnsubscribe = true; + } //use url or build a url from usetls://broker:port if (node.url && node.brokerurl !== node.url) { @@ -660,6 +664,7 @@ module.exports = function(RED) { node.options.password = node.password; node.options.keepalive = node.keepalive; node.options.clean = node.cleansession; + node.options.autoUnsubscribe = node.autoUnsubscribe; node.options.clientId = node.clientid || 'nodered_' + RED.util.generateId(); node.options.reconnectPeriod = RED.settings.mqttReconnectTime||5000; delete node.options.protocolId; //V4+ default @@ -1228,12 +1233,16 @@ module.exports = function(RED) { node.on('close', function(removed, done) { if (node.brokerConn) { if(node.isDynamic) { - Object.keys(node.dynamicSubs).forEach(function (topic) { - node.brokerConn.unsubscribe(topic, node.id, removed); - }); - node.dynamicSubs = {}; + if (node.brokerConn.options.autoUnsubscribe) { + Object.keys(node.dynamicSubs).forEach(function (topic) { + node.brokerConn.unsubscribe(topic, node.id, removed); + }); + node.dynamicSubs = {}; + } } else { - node.brokerConn.unsubscribe(node.topic,node.id, removed); + if (node.brokerConn.options.autoUnsubscribe) { + node.brokerConn.unsubscribe(node.topic, node.id, removed); + } } node.brokerConn.deregister(node, done, removed); node.brokerConn = null; diff --git a/packages/node_modules/@node-red/nodes/locales/de/messages.json b/packages/node_modules/@node-red/nodes/locales/de/messages.json index 65f251e98..4ac593504 100644 --- a/packages/node_modules/@node-red/nodes/locales/de/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/de/messages.json @@ -362,6 +362,7 @@ "port": "Port", "keepalive": "Keep-Alive", "cleansession": "Bereinigte Sitzung (clean session) verwenden", + "autoUnsubscribe": "Abonnement bei Verbindungsende automatisch beenden", "cleanstart": "Verwende bereinigten Start", "use-tls": "TLS", "tls-config": "TLS-Konfiguration", diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json index 66c492dc8..801aeace8 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json @@ -414,6 +414,7 @@ "port": "Port", "keepalive": "Keep Alive", "cleansession": "Use clean session", + "autoUnsubscribe": "Automatically unsubscribe when disconnecting", "cleanstart": "Use clean start", "use-tls": "Use TLS", "tls-config": "TLS Configuration", diff --git a/test/nodes/core/network/21-mqtt_spec.js b/test/nodes/core/network/21-mqtt_spec.js index f97442b50..16c38d2e5 100644 --- a/test/nodes/core/network/21-mqtt_spec.js +++ b/test/nodes/core/network/21-mqtt_spec.js @@ -53,7 +53,7 @@ describe('MQTT Nodes', function () { mqttBroker.should.have.property('broker', BROKER_HOST); mqttBroker.should.have.property('port', BROKER_PORT); mqttBroker.should.have.property('brokerurl'); - // mqttBroker.should.have.property('autoUnsubscribe', true);//default: true + mqttBroker.should.have.property('autoUnsubscribe', true); //default: true mqttBroker.should.have.property('autoConnect', false);//Set "autoConnect:false" in brokerOptions mqttBroker.should.have.property('options'); mqttBroker.options.should.have.property('clean', true); @@ -96,8 +96,8 @@ describe('MQTT Nodes', function () { mqttBroker.should.have.property('broker', BROKER_HOST); mqttBroker.should.have.property('port', BROKER_PORT); mqttBroker.should.have.property('brokerurl'); - // mqttBroker.should.have.property('autoUnsubscribe', true);//default: true - mqttBroker.should.have.property('autoConnect', false);//Set "autoConnect:false" in brokerOptions + mqttBroker.should.have.property('autoUnsubscribe', true); + mqttBroker.should.have.property('autoConnect', false); //Set "autoConnect:false" in brokerOptions mqttBroker.should.have.property('options'); mqttBroker.options.should.have.property('clean', false); mqttBroker.options.should.have.property('clientId', 'clientid');