node-red-iot-mqtt-api
Version:
return right result to node-red
1,226 lines (1,182 loc) • 43.1 kB
HTML
<!--
Copyright JS Foundation and other contributors, http://js.foundation
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.
-->
<style>
.mqtt-form-row-cols2 > input.mqtt-form-row-col1 {
width: calc(35% - 75px);
}
.mqtt-form-row-cols2 > select.mqtt-form-row-col1 {
width: calc(35% - 75px);
}
.mqtt-form-row-cols2 > label.mqtt-form-row-col2 {
width: 100px;
margin-left: 42px;
display: inline-block;
}
.mqtt-form-row-cols2 > input.mqtt-form-row-col2 {
width: calc(35% - 75px);
display: inline-block;
}
.mqtt-form-row-cols2 > select.mqtt-form-row-col2 {
width: calc(35% - 75px);
display: inline-block;
}
.form-row.mqtt5-out > label {
width: 130px;
}
.form-row.mqtt-flags-row > label {
vertical-align: top;
}
.form-row.mqtt-flags-row > .mqtt-flags {
display: inline-block;
width: 70%;
}
.form-row.mqtt-flags-row > .mqtt-flags > .mqtt-flag > label {
display: block;
width: 100%;
}
.form-row.mqtt-flags-row > .mqtt-flags > .mqtt-flag > label > input {
position: relative;
vertical-align: bottom;
top: -2px;
width: 15px;
height: 15px;
}
.form-row-mqtt5 {
display: none;
}
.form-row-mqtt5.form-row-mqtt5-active:not(.form-row-mqtt-static-disabled) {
display: block;
}
.form-row-mqtt-static-disabled {
display: none;
/* opacity: 0.3;
pointer-events: none; */
}
.form-row.form-row-mqtt-datatype-tip > .form-tips {
width: calc(70% - 18px);
display: inline-block;
margin-top: -8px;
}
</style>
<style>
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
margin-left: 2px;
}
/* Tooltip text */
.tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 5px;
/* Position the tooltip text */
position: absolute;
z-index: 1;
top: 100%;
left: 50%;
margin-left: -60px; /* Use half of the width (120px/2 = 60px), to center the tooltip */
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
}
</style>
<script type="text/html" data-template-name="iot-mqtt-in">
<div class="form-row">
<label for="node-input-broker"
><i class="fa fa-globe"></i> <span data-i18n="mqtt.label.broker"></span
></label>
<input type="text" id="node-input-broker" />
</div>
<!-- <div class="form-row">
<label for="node-input-topicType" data-i18n="mqtt.label.action"></label>
<select id="node-input-topicType" style="width: 70%">
<option value="topic" data-i18n="mqtt.label.staticTopic"></option>
<option value="dynamic" data-i18n="mqtt.label.dynamicTopic"></option>
</select>
<input type="hidden" id="node-input-inputs">
</div> -->
<div class="form-row">
<label for="node-input-topicCategory">主题选择</label>
<select id="node-input-topicCategory" style="width: 70%">
<option value="online">设备上线</option>
<option value="eventUp">事件上报</option>
<option value="serviceInvoke">服务调用</option>
<option value="propertySet">属性设置</option>
<option value="propertyGet">属性获取</option>
<option value="propertyPost">属性上报</option>
<option value="deviceConfigGet">设备获取配置</option>
<option value="deviceConfigSet">设备获取下发</option>
</select>
<input type="hidden" id="node-input-inputs" />
</div>
<div class="form-row form-row-mqtt-eventName">
<label
for="node-input-eventName"
data-i18n="common.label.eventName"
></label>
<input
type="text"
id="node-input-eventName"
data-i18n="[placeholder]common.label.eventName"
/>
</div>
<div class="form-row form-row-mqtt-serviceName">
<label
for="node-input-serviceName"
data-i18n="common.label.serviceName"
></label>
<input
type="text"
id="node-input-serviceName"
data-i18n="[placeholder]common.label.serviceName"
/>
</div>
<!-- <div class="form-row form-row-mqtt-static">
<label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
<input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic">
</div> -->
<div class="form-row form-row-mqtt-static">
<label for="node-input-qos"
><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span
></label>
<select id="node-input-qos" style="width:125px !important">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
<div class="form-row mqtt-flags-row form-row-mqtt5 form-row-mqtt-static">
<label for="node-input-nl"
><i class="fa fa-flag"></i>
<span data-i18n="mqtt.label.flags">Flags</span></label
>
<div class="mqtt-flags">
<div class="mqtt-flag">
<label for="node-input-nl">
<input type="checkbox" id="node-input-nl" />
<span data-i18n="mqtt.label.nl"></span>
</label>
</div>
<div class="mqtt-flag">
<label for="node-input-rap">
<input type="checkbox" id="node-input-rap" />
<span data-i18n="mqtt.label.rap"></span>
</label>
</div>
</div>
</div>
<div class="form-row form-row-mqtt5 form-row-mqtt-static">
<label for="node-input-rh" style="width:100%"
><i class="fa fa-tag"></i> <span data-i18n="mqtt.label.rh"></span
></label>
<select id="node-input-rh" style="margin-left: 104px; width: 70%">
<option value="0" data-i18n="mqtt.label.rh0"></option>
<option value="1" data-i18n="mqtt.label.rh1"></option>
<option value="2" data-i18n="mqtt.label.rh2"></option>
</select>
</div>
<div class="form-row">
<label for="node-input-datatype"
><i class="fa fa-sign-out"></i> <span data-i18n="mqtt.label.output"></span
></label>
<select id="node-input-datatype" style="width:70%;">
<option value="auto-detect" data-i18n="mqtt.output.auto-detect"></option>
<option value="auto" data-i18n="mqtt.output.auto"></option>
<option value="buffer" data-i18n="mqtt.output.buffer"></option>
<option value="utf8" data-i18n="mqtt.output.string"></option>
<option value="json" data-i18n="mqtt.output.json"></option>
<option value="base64" data-i18n="mqtt.output.base64"></option>
</select>
</div>
<div class="form-row form-row-mqtt-datatype-tip">
<label> </label>
<div class="form-tips" id="mqtt-in-datatype-depreciated-tip">
<span data-i18n="mqtt.label.auto-mode-depreciated"></span>
</div>
</div>
<div class="form-row">
<label for="node-input-name"
><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span
></label>
<input
type="text"
id="node-input-name"
data-i18n="[placeholder]common.label.name"
/>
</div>
</script>
<script type="text/html" data-template-name="iot-mqtt-out">
<div class="form-row">
<label for="node-input-broker"
><i class="fa fa-globe"></i> <span data-i18n="mqtt.label.broker"></span
></label>
<input type="text" id="node-input-broker" />
</div>
<div class="form-row">
<label for="node-input-topicCategory"
><i class="fa fa-tasks"></i>主题选择</label
>
<!-- <input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic"> -->
<select id="node-input-topicCategory">
<option value="eventUp">事件上报</option>
<option value="serviceInvoke">服务调用</option>
<option value="propertySet">属性设置</option>
<option value="propertyGet">属性获取</option>
<option value="propertyPost">属性上报</option>
<option value="deviceConfigGet">设备获取配置</option>
<option value="deviceConfigSet">设备获取下发</option>
</select>
</div>
<div class="form-row form-row-mqtt-eventName">
<label for="node-input-eventName"
><i class="fa fa-tasks"></i>
<span data-i18n="common.label.eventName"></span
></label>
<input
type="text"
id="node-input-eventName"
data-i18n="[placeholder]common.label.eventName"
/>
</div>
<div class="form-row form-row-mqtt-serviceName">
<label for="node-input-serviceName"
><i class="fa fa-tasks"></i>
<span data-i18n="common.label.serviceName"></span
></label>
<input
type="text"
id="node-input-serviceName"
data-i18n="[placeholder]common.label.serviceName"
/>
</div>
<div class="form-row mqtt-form-row-cols2">
<label for="node-input-qos" class="mqtt-form-row-col1"
><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span
></label>
<select id="node-input-qos" class="mqtt-form-row-col1">
<option value=""></option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<label for="node-input-retain" class="mqtt-form-row-col2"
><i class="fa fa-history"></i> <span data-i18n="mqtt.retain"></span
></label>
<select id="node-input-retain" class="mqtt-form-row-col2">
<option value=""></option>
<option value="false" data-i18n="mqtt.false"></option>
<option value="true" data-i18n="mqtt.true"></option>
</select>
</div>
<div class="form-row mqtt5 mqtt5-out">
<label for="node-input-userProps"
><span data-i18n="mqtt.label.userProperties"></span
></label>
<input
type="text"
id="node-input-userProps"
style="width: calc(100% - 166px);"
/>
</div>
<div class="form-row mqtt5 mqtt5-out">
<label for="node-input-respTopic"
><span data-i18n="mqtt.label.responseTopic"></span
></label>
<input
type="text"
id="node-input-respTopic"
style="width: calc(100% - 166px);"
/>
</div>
<div class="form-row mqtt5 mqtt5-out">
<label for="node-input-correl"
><span data-i18n="mqtt.label.correlationData"></span
></label>
<input
type="text"
id="node-input-correl"
style="width: calc(100% - 166px);"
/>
</div>
<div class="form-row mqtt5 mqtt5-out">
<label for="node-input-contentType"
><span data-i18n="mqtt.label.contentType"></span
></label>
<input
type="text"
id="node-input-contentType"
style="width: calc(100% - 166px);"
/>
</div>
<div class="form-row mqtt-form-row-cols2 mqtt5 mqtt5-out">
<label for="node-input-expiry" class="mqtt-form-row-col1"
><span data-i18n="mqtt.label.expiry"></span
></label>
<input
id="node-input-expiry"
style="width: calc(100% - 166px);"
class="mqtt-form-row-col1"
/>
</div>
<div class="form-row">
<label for="node-input-name"
><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span
></label>
<input
type="text"
id="node-input-name"
data-i18n="[placeholder]common.label.name"
/>
</div>
<div class="form-tips"><span data-i18n="mqtt.tip"></span></div>
</script>
<script type="text/html" data-template-name="iot-mqtt-broker">
<div class="form-row">
<label for="node-config-input-name"
><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span
></label>
<input
type="text"
id="node-config-input-name"
data-i18n="[placeholder]common.label.name"
/>
</div>
<div class="form-row">
<ul
style="min-width: 600px; margin-bottom: 20px;"
id="node-config-iot-mqtt-broker-tabs"
></ul>
</div>
<div id="node-config-iot-mqtt-broker-tabs-content" style="min-height:150px;">
<div id="iot-mqtt-broker-tab-connection" style="display:none">
<div class="form-row node-input-broker">
<label for="node-config-input-broker"
><i class="fa fa-globe"></i>
<span data-i18n="mqtt.label.broker"></span
></label>
<input
type="text"
id="node-config-input-broker"
style="width: calc(100% - 300px);"
data-i18n="[placeholder]mqtt.label.example"
/>
<label
for="node-config-input-port"
style="margin-left:20px; width:43px; "
>
<span data-i18n="mqtt.label.port"></span
></label>
<input
type="text"
id="node-config-input-port"
data-i18n="[placeholder]mqtt.label.port"
style="width:55px"
/>
</div>
<div class="form-row" style="margin-bottom:0">
<input
type="checkbox"
id="node-config-input-autoConnect"
style="margin: 0 5px 0 104px; display: inline-block; width: auto;"
/>
<label for="node-config-input-autoConnect" style="width: auto"
><span data-i18n="mqtt.label.auto-connect"></span
></label>
</div>
<div class="form-row" style="height: 34px;">
<input
type="checkbox"
id="node-config-input-usetls"
style="height: 34px; margin: 0 5px 0 104px; display: inline-block; width: auto; vertical-align: top;"
/>
<label
for="node-config-input-usetls"
style="width: 100px; line-height: 34px;"
><span data-i18n="mqtt.label.use-tls"></span
></label>
<span id="node-config-row-tls" class="hide"
><input style="width: 320px;" type="text" id="node-config-input-tls"
/></span>
</div>
<div class="form-row">
<label for="node-config-input-protocolVersion"
><i class="fa fa-cog"></i>
<span data-i18n="mqtt.label.protocolVersion"></span
></label>
<select id="node-config-input-protocolVersion" style="width:70%;">
<option value="3" data-i18n="mqtt.label.protocolVersion3"></option>
<option value="4" data-i18n="mqtt.label.protocolVersion4"></option>
<option value="5" data-i18n="mqtt.label.protocolVersion5"></option>
</select>
</div>
<!-- <div class="form-row">
<label for="node-config-input-clientid"><i class="fa fa-tag"></i> <span data-i18n="mqtt.label.clientid"></span></label>
<input type="text" id="node-config-input-clientid" data-i18n="[placeholder]mqtt.placeholder.clientid">
</div> -->
<div class="form-row">
<label for="node-config-input-model">
<i class="fa fa-cubes"></i> <span data-i18n="mqtt.label.model"></span>
<span class="tooltip"
><i class="fa fa-question-circle"></i
><span class="tooltiptext">设备型号,用于标识不同设备</span></span
>
</label>
<input
type="text"
id="node-config-input-model"
data-i18n="[placeholder]mqtt.placeholder.model"
/>
</div>
<div class="form-row">
<label for="node-config-input-deviceName"
><i class="fa fa-desktop"></i>
<span data-i18n="mqtt.label.deviceName"></span>
<span class="tooltip"
><i class="fa fa-question-circle"></i
><span class="tooltiptext"
>iot平台-设备接入-设备列表-设备deviceName</span
></span
>
</label>
<input
type="text"
id="node-config-input-deviceName"
data-i18n="[placeholder]mqtt.placeholder.deviceName"
/>
</div>
<div class="form-row">
<label for="node-config-input-secrete"
><i class="fa fa-user-secret"></i>
<span data-i18n="mqtt.label.secrete"></span
><span class="tooltip"
><i class="fa fa-question-circle"></i
><span class="tooltiptext"
>iot平台-设备接入-设备列表-设备秘钥</span
></span
></label
>
<input
type="text"
id="node-config-input-secrete"
data-i18n="[placeholder]mqtt.placeholder.secrete"
/>
</div>
<div class="form-row">
<label for="node-config-input-productKey"
><i class="fa fa-key"></i>
<span data-i18n="mqtt.label.productKey"></span>
<span class="tooltip"
><i class="fa fa-question-circle"></i
><span class="tooltiptext"
>iot平台-设备接入-设备列表-详情-产品productKey</span
></span
>
</label>
<input
type="text"
id="node-config-input-productKey"
data-i18n="[placeholder]mqtt.placeholder.productKey"
/>
</div>
<div class="form-row">
<label for="node-config-input-keepalive"
><i class="fa fa-heartbeat"></i>
<span data-i18n="mqtt.label.keepalive"></span
></label>
<input
type="number"
min="0"
id="node-config-input-keepalive"
style="width: 100px"
/>
</div>
<div class="form-row" style="margin-bottom:0">
<label style="vertical-align:top;"
><i class="fa fa-info"></i>
<span data-i18n="mqtt.label.session"></span
></label>
<div style="display: inline-block; width:calc(100% - 110px)">
<div class="form-row">
<label for="node-config-input-cleansession" style="width: auto;">
<input
type="checkbox"
id="node-config-input-cleansession"
style="position: relative;vertical-align: bottom; top: -2px; width: 15px;height: 15px;"
/>
<span
id="node-config-input-cleansession-label"
data-i18n="mqtt.label.cleansession"
></span>
</label>
</div>
<div class="form-row mqtt5">
<label style="width:auto" for="node-config-input-sessionExpiry"
><span data-i18n="mqtt.label.sessionExpiry"></span
></label>
<input
type="number"
min="0"
id="node-config-input-sessionExpiry"
style="width: 100px"
/>
</div>
</div>
</div>
<div class="form-row mqtt5">
<label style="width: 125px;" for="node-config-input-userProps"
><span data-i18n="mqtt.label.userProperties"></span
></label>
<input
type="text"
id="node-config-input-userProps"
style="width: calc(100% - 166px);"
/>
</div>
<br />
</div>
</div>
</script>
<script type="text/javascript">
(function () {
var typedInputNoneOpt = {
value: "none",
label: RED._("node-red:mqtt.label.none"),
hasValue: false,
};
var makeTypedInputOpt = function (value) {
return {
value: value,
label: value,
hasValue: false,
};
};
var contentTypeOpts = [
typedInputNoneOpt,
makeTypedInputOpt("application/json"),
makeTypedInputOpt("application/octet-stream"),
makeTypedInputOpt("text/csv"),
makeTypedInputOpt("text/html"),
makeTypedInputOpt("text/plain"),
{
value: "other",
label: RED._("node-red:mqtt.label.other"),
icon: "red/images/typedInput/az.svg",
},
];
function getDefaultContentType(value) {
var defaultContentType;
var matchedContentType = contentTypeOpts.filter(function (v) {
return v.value === value;
});
if (matchedContentType.length > 0) {
defaultContentType = matchedContentType[0].value;
}
if (value && !defaultContentType) {
defaultContentType = "other";
}
return defaultContentType || "none";
}
/**
* Test a topic string is valid for publishing
* @param {string} topic
* @returns `true` if it is a valid topic
*/
function validateMQTTPublishTopic(topic, opts) {
if (!topic || topic == "" || !/[\+#\b\f\n\r\t\v\0]/.test(topic)) {
return true;
}
return RED._("node-red:mqtt.errors.invalid-topic");
}
RED.nodes.registerType("iot-mqtt-broker", {
category: "config",
defaults: {
secrete: { value: "", required: true },
model: { value: "", required: true },
deviceName: { value: "", required: true },
productKey: { value: "", required: true },
name: { value: "" },
broker: { value: "", required: true },
port: {
value: 1883,
required: false,
label: RED._("node-red:mqtt.label.port"),
validate: RED.validators.number(true),
},
tls: {
type: "tls-config",
required: false,
label: RED._("node-red:mqtt.label.use-tls"),
},
// clientid: {value:"", validate: function(v, opt) {
// var ok = false;
// if ($("#node-config-input-clientid").length) {
// // Currently editing the node
// ok = $("#node-config-input-cleansession").is(":checked") || (v||"").length > 0;
// } else {
// ok = (this.cleansession===undefined || this.cleansession) || (v||"").length > 0;
// }
// if (ok) {
// return ok;
// }
// return RED._("node-red:mqtt.errors.invalid-client-id");
// }},
autoConnect: { value: true },
usetls: { value: false },
verifyservercert: { value: false },
compatmode: { value: false },
protocolVersion: { value: 4 },
keepalive: {
value: 60,
label: RED._("node-red:mqtt.label.keepalive"),
validate: RED.validators.number(false),
},
cleansession: { value: true },
birthTopic: { value: "", validate: validateMQTTPublishTopic },
birthQos: { value: "0" },
birthRetain: { value: "false" },
birthPayload: { value: "" },
birthMsg: { value: {} },
closeTopic: { value: "", validate: validateMQTTPublishTopic },
closeQos: { value: "0" },
closeRetain: { value: "false" },
closePayload: { value: "" },
closeMsg: { value: {} },
willTopic: { value: "", validate: validateMQTTPublishTopic },
willQos: { value: "0" },
willRetain: { value: "false" },
willPayload: { value: "" },
willMsg: { value: {} },
userProps: { value: "" },
sessionExpiry: { value: 0 },
},
credentials: {
user: { type: "text" },
password: { type: "password" },
},
label: function () {
if (this.name) {
return this.name;
}
var b = this.broker;
if (!b) {
b = "undefined";
}
var lab = "";
lab = (this.clientid ? this.clientid + "@" : "") + b;
if (b.indexOf("://") === -1) {
if (!this.port) {
lab = lab + ":1883";
} else {
lab = lab + ":" + this.port;
}
}
return lab;
},
oneditprepare: function () {
var tabs = RED.tabs.create({
id: "node-config-iot-mqtt-broker-tabs",
onchange: function (tab) {
$("#node-config-iot-mqtt-broker-tabs-content").children().hide();
$("#" + tab.id).show();
},
});
tabs.addTab({
id: "iot-mqtt-broker-tab-connection",
label: this._("mqtt.tabs-label.connection"),
});
function setUpSection(sectionId, v5Opts, isExpanded) {
var birthMessageSection = $("#iot-mqtt-broker-section-" + sectionId);
var paletteHeader = birthMessageSection.find(
".red-ui-palette-header"
);
var twistie = paletteHeader.find("i");
var sectionContent = birthMessageSection.find(".section-content");
function toggleSection(expanded) {
twistie.toggleClass("expanded", expanded);
sectionContent.toggle(expanded);
}
paletteHeader.on("click", function (e) {
e.preventDefault();
var isExpanded = twistie.hasClass("expanded");
toggleSection(!isExpanded);
});
toggleSection(isExpanded);
$("#node-config-input-" + sectionId + "-contentType")
.val(v5Opts ? v5Opts.contentType : "")
.typedInput({
default: getDefaultContentType(v5Opts ? v5Opts.contentType : ""),
types: contentTypeOpts,
});
$("#node-config-input-" + sectionId + "-props")
.val(v5Opts ? v5Opts.userProps : "")
.typedInput({
default: !(v5Opts ? v5Opts.userProps : null) ? "none" : "json",
types: [typedInputNoneOpt, "json"],
});
$("#node-config-input-" + sectionId + "-respTopic")
.val(v5Opts ? v5Opts.respTopic : "")
.typedInput({
default: !(v5Opts ? v5Opts.respTopic : null) ? "none" : "str",
types: [typedInputNoneOpt, "str"],
});
$("#node-config-input-" + sectionId + "-correl")
.val(v5Opts ? v5Opts.correl : "")
.typedInput({
default: !(v5Opts ? v5Opts.correl : null) ? "none" : "str",
types: [typedInputNoneOpt, "str"],
});
$("#node-config-input-" + sectionId + "-expiry")
.val(v5Opts ? v5Opts.expiry : "")
.typedInput({
default: !(v5Opts ? v5Opts.expiry : null) ? "none" : "num",
types: [typedInputNoneOpt, "num"],
});
}
// show first section if none are set so the user gets the idea
var showBirthSection =
this.birthTopic !== "" ||
(this.willTopic === "" &&
this.birthTopic === "" &&
this.closeTopic == "");
setUpSection("birth", this.birthMsg, showBirthSection);
setUpSection("close", this.closeMsg, this.closeTopic !== "");
setUpSection("will", this.willMsg, this.willTopic !== "");
if (this.willMsg) {
$("#node-config-input-will-delay").val(this.willMsg.delay);
}
setTimeout(function () {
tabs.resize();
}, 0);
if (typeof this.cleansession === "undefined") {
this.cleansession = true;
$("#node-config-input-cleansession").prop("checked", true);
}
if (typeof this.usetls === "undefined") {
this.usetls = false;
$("#node-config-input-usetls").prop("checked", false);
}
if (typeof this.autoConnect === "undefined") {
this.autoConnect = true;
$("#node-config-input-autoConnect").prop("checked", true);
}
if (this.compatmode === "true" || this.compatmode === true) {
delete this.compatmode;
this.protocolVersion = 4;
}
if (typeof this.protocolVersion === "undefined") {
this.protocolVersion = 4;
}
$("#node-config-input-protocolVersion").on("change", function () {
var v5 = $("#node-config-input-protocolVersion").val() == "5";
if (v5) {
$("#node-config-input-cleansession-label").text(
RED._("node-red:mqtt.label.cleanstart")
);
$("div.form-row.mqtt5").show();
} else {
$("#node-config-input-cleansession-label").text(
RED._("node-red:mqtt.label.cleansession")
);
$("div.form-row.mqtt5").hide();
}
});
$("#node-config-input-protocolVersion").val(this.protocolVersion);
$("#node-config-input-userProps").typedInput({
default: !this.userProps ? "none" : "json",
types: [typedInputNoneOpt, "json"],
});
$("#node-config-input-userProps").typedInput("value", this.userProps);
if (typeof this.keepalive === "undefined") {
this.keepalive = 15;
$("#node-config-input-keepalive").val(this.keepalive);
}
if (typeof this.birthQos === "undefined") {
this.birthQos = "0";
$("#node-config-input-birthQos").val("0");
}
if (typeof this.closeQos === "undefined") {
this.willQos = "0";
$("#node-config-input-willQos").val("0");
}
if (typeof this.willQos === "undefined") {
this.willQos = "0";
$("#node-config-input-willQos").val("0");
}
function updateTLSOptions() {
if ($("#node-config-input-usetls").is(":checked")) {
$("#node-config-row-tls").show();
} else {
$("#node-config-row-tls").hide();
}
}
updateTLSOptions();
$("#node-config-input-usetls").on("click", function () {
updateTLSOptions();
});
var node = this;
function updateClientId() {
if ($("#node-config-input-cleansession").is(":checked")) {
$("#node-config-input-clientid").attr(
"placeholder",
node._("mqtt.placeholder.clientid")
);
} else {
$("#node-config-input-clientid").attr(
"placeholder",
node._("mqtt.placeholder.clientid-nonclean")
);
}
$("#node-config-input-clientid").trigger("change");
}
setTimeout(updateClientId, 0);
$("#node-config-input-cleansession").on("click", function () {
updateClientId();
});
function updatePortEntry() {
var disabled = $("#node-config-input-port").prop("disabled");
if ($("#node-config-input-broker").val().indexOf("://") === -1) {
if (disabled) {
$("#node-config-input-port").prop("disabled", false);
}
} else {
if (!disabled) {
$("#node-config-input-port").prop("disabled", true);
}
}
}
$("#node-config-input-broker").on("change", function () {
updatePortEntry();
});
$("#node-config-input-broker").on("keyup", function () {
updatePortEntry();
});
setTimeout(updatePortEntry, 50);
setTimeout(function () {
$("#node-config-input-protocolVersion").trigger("change");
}, 50);
},
oneditsave: function () {
if (!$("#node-config-input-usetls").is(":checked")) {
$("#node-config-input-tls").val("");
}
var v5 = $("#node-config-input-protocolVersion").val() == "5";
function saveV5Message(section) {
var msg = {};
if (
$("#node-config-input-" + section + "Topic")
.val()
.trim().length > 0
) {
var contentType = $(
"#node-config-input-" + section + "-contentType"
)
.val()
.trim();
if (contentType === "") {
contentType = $(
"#node-config-input-" + section + "-contentType"
).typedInput("type");
if (contentType === "none" || contentType === "other") {
contentType = "";
}
}
if (contentType) {
msg.contentType = contentType;
}
var props = $("#node-config-input-" + section + "-props")
.val()
.trim();
if (props) {
msg.userProps = props;
}
var resp = $("#node-config-input-" + section + "-respTopic")
.val()
.trim();
if (props) {
msg.respTopic = resp;
}
var correl = $("#node-config-input-" + section + "-correl")
.val()
.trim();
if (correl) {
msg.correl = correl;
}
var expiry = $("#node-config-input-" + section + "-expiry")
.val()
.trim();
if (expiry) {
msg.expiry = expiry;
}
}
return msg;
}
if (v5) {
this.userProps = "";
const userPropsType = $("#node-config-input-userProps").typedInput(
"type"
);
if (userPropsType == "json") {
const userProps = $("#node-config-input-userProps").val();
if (userProps && typeof userProps === "string") {
this.userProps = userProps.trim();
}
}
this.birthMsg = saveV5Message("birth");
this.closeMsg = saveV5Message("close");
this.willMsg = saveV5Message("will");
var willDelay = $("#node-config-input-will-delay").val();
if (willDelay) {
this.willMsg.delay = willDelay;
}
} else {
this.willMsg = {};
this.birthMsg = {};
this.closeMsg = {};
}
},
});
RED.nodes.registerType("iot-mqtt-in", {
category: "network",
defaults: {
name: { value: "" },
topicCategory: { value: "", required: true },
eventName: { value: "" },
serviceName: { value: "" },
// topic: {
// value:"",
// validate: function(v, opt) {
// var isDynamic = this.inputs === 1;
// var topicTypeSelect = $("#node-input-topicType");
// if (topicTypeSelect.length) {
// isDynamic = topicTypeSelect.val()==='dynamic'
// }
// if (isDynamic || ((!!v) && RED.validators.regex(/^(#$|(\+|[^+#]*)(\/(\+|[^+#]*))*(\/(\+|#|[^+#]*))?$)/)(v))) {
// return true;
// }
// return RED._("node-red:mqtt.errors.invalid-topic");
// }
// },
qos: { value: "2" },
datatype: { value: "auto-detect", required: true },
broker: {
type: "iot-mqtt-broker",
required: true,
label: RED._("node-red:mqtt.label.broker"),
},
// subscriptionIdentifier: {value:0},
nl: { value: false },
rap: { value: true },
rh: { value: 0 },
inputs: { value: 0 },
},
color: "#d8bfd8",
inputs: 0,
outputs: 1,
icon: "bridge.svg",
label: function () {
var label = "mqtt";
if (this.topicType !== "dynamic" && this.topic) {
label = this.topic;
}
return this.name || label;
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
},
oneditprepare: function () {
const node = this;
const isV5Broker = function () {
var confNode = RED.nodes.node($("#node-input-broker").val());
return confNode && confNode.protocolVersion === "5";
};
const isDynamic = function () {
return $("#node-input-topicType").val() === "dynamic";
};
const updateVisibility = function () {
var v5 = isV5Broker();
var dynamic = isDynamic();
$("div.form-row-mqtt5").toggleClass("form-row-mqtt5-active", !!v5);
$("div.form-row.form-row-mqtt-static").toggleClass(
"form-row-mqtt-static-disabled",
!!dynamic
);
};
function showHideEventName() {
var topicCategory = $("#node-input-topicCategory").val();
if (topicCategory === "eventUp") {
$(".form-row-mqtt-eventName").show();
} else {
$(".form-row-mqtt-eventName").hide();
}
}
function showHideServiceName() {
var topicCategory = $("#node-input-topicCategory").val();
if (topicCategory === "serviceInvoke") {
$(".form-row-mqtt-serviceName").show();
} else {
$(".form-row-mqtt-serviceName").hide();
}
}
$("#node-input-topicCategory").on("change", function (d) {
showHideEventName();
showHideServiceName();
});
$("#node-input-datatype").on("change", function () {
if ($(this).val() === "auto") {
$(".form-row.form-row-mqtt-datatype-tip").show();
} else {
$(".form-row.form-row-mqtt-datatype-tip").hide();
}
});
$("#node-input-datatype").trigger("change");
$("#node-input-broker").on("change", function (d) {
updateVisibility();
});
$("#node-input-topicType").on("change", function () {
$("#node-input-inputs").val(isDynamic() ? 1 : 0);
updateVisibility();
});
if (this.inputs === 1) {
$("#node-input-topicType").val("dynamic");
} else {
$("#node-input-topicType").val("topic");
}
$("#node-input-topicType").trigger("change");
if (this.qos === undefined) {
$("#node-input-qos").val("2");
}
if (this.datatype === undefined) {
$("#node-input-datatype").val("auto-detect");
}
},
oneditsave: function () {
if ($("#node-input-topicType").val() === "dynamic") {
$("#node-input-topic").val("");
}
},
});
RED.nodes.registerType("iot-mqtt-out", {
category: "network",
defaults: {
topicCategory: { value: "online", required: true },
eventName: { value: "" },
serviceName: { value: "" },
name: { value: "" },
// topic: {value:"", validate:validateMQTTPublishTopic},
qos: { value: "" },
retain: { value: "" },
respTopic: { value: "" },
contentType: { value: "" },
userProps: { value: "" },
correl: { value: "" },
expiry: { value: "" },
broker: {
type: "iot-mqtt-broker",
required: true,
label: RED._("node-red:mqtt.label.broker"),
},
},
color: "#d8bfd8",
inputs: 1,
outputs: 0,
icon: "bridge.svg",
align: "right",
label: function () {
return this.name || this.topic || "mqtt";
},
oneditprepare: function () {
var that = this;
function showHideDynamicFields() {
var confNode = RED.nodes.node($("#node-input-broker").val());
var v5 = confNode && confNode.protocolVersion == "5";
if (v5) {
$("div.form-row.mqtt5").show();
var t = $("#node-input-respTopic").typedInput("type");
if (t == "none") {
$("#node-input-correl").parent().hide();
} else {
$("#node-input-correl").parent().show();
}
} else {
$("div.form-row.mqtt5").hide();
}
}
function showHideEventName() {
var topicCategory = $("#node-input-topicCategory").val();
if (topicCategory === "eventUp") {
$(".form-row-mqtt-eventName").show();
} else {
$(".form-row-mqtt-eventName").hide();
}
}
function showHideServiceName() {
var topicCategory = $("#node-input-topicCategory").val();
if (topicCategory === "serviceInvoke") {
$(".form-row-mqtt-serviceName").show();
} else {
$(".form-row-mqtt-serviceName").hide();
}
}
$("#node-input-topicCategory").on("change", function (d) {
showHideEventName();
showHideServiceName();
});
$("#node-input-broker").on("change", function (d) {
showHideDynamicFields();
});
var respTopicTI = $("#node-input-respTopic").typedInput({
default: !this.respTopic ? "none" : "str",
types: [typedInputNoneOpt, "str"],
});
var correlTI = $("#node-input-correl").typedInput({
default: !this.correl ? "none" : "str",
types: [typedInputNoneOpt, "str"],
});
//show / hide correlation data depending on respTopic
respTopicTI.on("change", showHideDynamicFields);
respTopicTI.triggerHandler("change");
$("#node-input-userProps").typedInput({
default: !this.userProps ? "none" : "json",
types: [typedInputNoneOpt, "json"],
});
$("#node-input-expiry").typedInput({
default: !this.expiry ? "none" : "num",
types: [typedInputNoneOpt, "num"],
});
$("#node-input-contentType").typedInput({
default: getDefaultContentType(this.contentType),
types: contentTypeOpts,
});
},
oneditsave: function () {
var contentType = $("#node-input-contentType").val().trim();
if (contentType === "") {
contentType = $("#node-input-contentType").typedInput("type");
if (contentType === "none" || contentType === "other") {
contentType = "";
}
}
$("#node-input-contentType").val(contentType);
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
},
});
})();
</script>