UNPKG

@thingweb/node-red-node-wot

Version:
262 lines (231 loc) 10.6 kB
<!-- import tdUtils --> <script type="module" src="/resources/@thingweb/node-red-node-wot/@thingweb/td-utils/dist/web-bundle.min.js"></script> <script type="text/javascript"> // List of supported protocols // Secure ones (like https) are automatically inferred const PROTOCOLS = ["http", "ws", "coap", "mqtt", "opcua", "modbus"] function checkBinding(td_str, binding) { // In case of OPC UA we look for opc.tcp in href not opcua binding = binding === "opcua" ? "opc.tcp" : binding // Also different for Modbus binding = binding === "modbus" ? "modbus+tcp" : binding const bindings = Object.keys(tdUtils.detectProtocolSchemes(td_str)) return bindings.some(b => b === binding || b === binding + 's') } function containsID(td_str) { try { const td = JSON.parse(td_str) return !!td.id } catch (err) { return false } } RED.nodes.registerType("consumed-thing", { category: "config", defaults: { tdLink: { value: "", required: false }, td: { value: "", required: false }, //TODO: add validator to make sure that at least one is given http: { value: false }, ws: { value: false }, coap: { value: false }, mqtt: { value: false }, opcua: { value: false }, modbus: { value: false }, basicAuth: { value: false }, username: { value: "" }, password: { value: "" }, }, label: function () { if (this.name) return this.name try { const td = JSON.parse(this.td) return td.title } catch (err) { return "consumed-thing" } }, oneditprepare: function () { const node = this // Create typed json input from the usual one $("#node-config-input-td").typedInput({ type: "json", types: ["json"], }) // Store the most used selectors const $basicAuth = $("#node-config-input-basicAuth") const $username = $("#username-container") const $password = $("#password-container") // Create the basic auth tooltip const $basicAuthTooltip = $("#basicAuth-tooltip") $basicAuthTooltip.tooltip() // Initialize the state of protocol checkboxes node.td = $("#node-config-input-td").typedInput("value") for (const protocol of PROTOCOLS) { const $protocol = $("#node-config-input-" + protocol) // No TD means node has not been yet configured if (!node.td) { // Uncheck and disable everything $protocol.prop("checked", false) $protocol.prop("disabled", true) } else { // If node is already configured // Check the configured protocols $protocol.prop("checked", node[protocol]) // Enable the ones which are contained in the TD // Note: (disabled, !true) = enabled $protocol.prop("disabled", !checkBinding(node.td, protocol)) } } // Initialize the state of username and password containers $username.hide() $password.hide() // Initialize the state of basic auth // No TD means node has not been yet configured if (!node.td) { // Initial state $basicAuth.prop("checked", false) $basicAuth.prop("disabled", true) $basicAuthTooltip.prop("title", "TD must contain ID field for authentication") } else { // If node is already configured // Recreate the state $basicAuth.prop("checked", node.basicAuth) if ($basicAuth.prop("checked")) { $username.show() $password.show() } // Note: (disabled, !true) = enabled $basicAuth.prop("disabled", !containsID(node.td)) if ($basicAuth.prop("disabled")) { $basicAuthTooltip.prop("title", "TD must contain ID field for authentication") } $("#node-config-input-username").val = node.username $("#node-config-input-password").val = node.password } // Toggle username and password when basic auth is enabled/disabled $basicAuth.change(function (event) { // Check if event is triggered by user if (event.originalEvent) { $username.toggle() $password.toggle() } }) // Fetch TD from URL on button click $("#fetch-button").click(function () { const tdLink = $("#node-config-input-tdLink").val() if (tdLink) { node.tdLink = tdLink let request = new XMLHttpRequest() request.open("GET", tdLink) request.onload = function () { node.td = request.response $("#node-config-input-td").typedInput("value", request.response) // Recheck the state of protocol checkboxes for (const protocol of PROTOCOLS) { const $protocol = $("#node-config-input-" + protocol) $protocol.prop("checked", false) $protocol.prop("disabled", true) if (checkBinding(node.td, protocol)) { $protocol.prop("checked", true) $protocol.prop("disabled", false) } } // Check availability for basic authentication $basicAuth.prop("checked", false) if (!containsID(node.td)) { $basicAuth.prop("disabled", true) $basicAuthTooltip.prop("title", "TD must contain ID field for authentication") $username.hide() $password.hide() } else { $basicAuth.prop("disabled", false) $basicAuthTooltip.prop("title", "") } } request.send() } }) // Fetch TD from the input field on button click $("#process-button").click(function () { node.td = $("#node-config-input-td").typedInput("value") // Recheck the state of protocol checkboxes for (const protocol of PROTOCOLS) { const $protocol = $("#node-config-input-" + protocol) $protocol.prop("checked", false) $protocol.prop("disabled", true) if (checkBinding(node.td, protocol)) { $protocol.prop("checked", true) $protocol.prop("disabled", false) } } // Check availability for basic authentication $basicAuth.prop("checked", false) if (!containsID(node.td)) { $basicAuth.prop("disabled", true) $basicAuthTooltip.prop("title", "TD must contain ID field for authentication") $username.hide() $password.hide() } else { $basicAuth.prop("disabled", false) $basicAuthTooltip.prop("title", "") } }) }, }) </script> <script type="text/x-red" data-template-name="consumed-thing"> <div class="form-row"> <label for="node-config-input-td"><i class="fa fa-file-text"></i> TD JSON</label> <input type="text" id="node-config-input-td" placeholder='{"title":"My-Cool-Thing", ...}' style="width:60%"> <button type="button" id="process-button">Process</button> </div> <div class="form-row"> <p>Fetch TD from URL:</p> </div> <div class="form-row"> <label for="node-config-input-tdLink"><i class="fa fa-link"></i> Link to TD</label> <input type="url" id="node-config-input-tdLink" style="width:60%"> <button type="button" id="fetch-button">Fetch</button> </div> <p>Support the following bindings:</p> <div class="form-row"> <label for="node-config-input-http"> HTTP / HTTPS</label> <input type="checkbox" id="node-config-input-http"> </div> <div class="form-row"> <label for="node-config-input-ws"> WebSocket</label> <input type="checkbox" id="node-config-input-ws"> </div> <div class="form-row"> <label for="node-config-input-coap"> COAP / COAPS</label> <input type="checkbox" id="node-config-input-coap"> </div> <div class="form-row"> <label for="node-config-input-mqtt"> MQTT</label> <input type="checkbox" id="node-config-input-mqtt"> </div> <div class="form-row"> <label for="node-config-input-opcua"> OPC UA</label> <input type="checkbox" id="node-config-input-opcua"> </div> <div class="form-row"> <label for="node-config-input-modbus"> Modbus</label> <input type="checkbox" id="node-config-input-modbus"> </div> <p>Security:</p> <div class="form-row"> <label for="node-config-input-basicAuth">Use basic authentication</label> <span id="basicAuth-tooltip"><input type="checkbox" id="node-config-input-basicAuth"></span> </div> <div class="form-row" id="username-container"> <label for="node-config-input-username"><i class="fa fa-user"></i> Username</label> <input type="text" id="node-config-input-username" style="width:60%"> </div> <div class="form-row" id="password-container"> <label for="node-config-input-password"><i class="fa fa-lock"></i> Password</label> <input type="password" id="node-config-input-password" style="width:60%"> </div> </script> <!--TODO:--> <!-- - Validate TD--> <!-- - Move to JS editor-->