UNPKG

node-red-contrib-tasmota

Version:
202 lines (196 loc) 8.96 kB
<script type="text/html" data-template-name="Tasmota Sensor"> <div class="form-row"> <ul id="node-input-tasmota-tabs"></ul> </div> <div id="node-input-tabs-content"> <div id="tasmota-settings-tab" style="display:none"> <div class="form-row"> <label for="node-input-broker"><i class="fa fa-globe"></i> Broker</label> <input type="text" id="node-input-broker"> </div> <div class="form-row"> <label for="node-input-device"><i class="fa fa-dot-circle-o"></i> Device</label> <input type="text" id="node-input-device" placeholder="Device id (topic)"> </div> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> </div> <div class="form-row"> <label for="node-input-uidisabler"><i class="fa fa-bar-chart"></i> Dashboard</label> <label for="node-input-uidisabler" style="width:70%"> <input type="checkbox" id="node-input-uidisabler" style="display:inline-block; width:auto; vertical-align:baseline;"> Send enable/disable message </label> </div> <hr> <div class="form-row"> <label for="node-input-outputTopic"><i class="fa fa-tag"></i> Topic</label> <input type="text" id="node-input-outputTopic" placeholder="Set the topic for output messages"> </div> <label for="node-input-rule-container">Output channels payload:</label> <div class="form-row node-input-rule-container-row"> <input type="hidden" id="node-input-outputs"> <ol id="node-input-rule-container"></ol> </div> </div> <div id="tasmota-advanced-tab" style="display:none"> <div class="form-row"> <label for="node-input-fullTopic"><i class="fa fa-wrench"></i> Full topic</label> <input type="text" id="node-input-fullTopic" placeholder="Full topic (Default: %prefix%/%topic%/)"> </div> <div class="form-row"> <label for="node-input-cmndPrefix"><i class="fa fa-comment"></i> cmnd</label> <input type="text" id="node-input-cmndPrefix" placeholder="Command topic prefix (Default: cmnd)"> </div> <div class="form-row"> <label for="node-input-statPrefix"><i class="fa fa-comment"></i> stat</label> <input type="text" id="node-input-statPrefix" placeholder="Stat topic prefix (Default: stat)"> </div> <div class="form-row"> <label for="node-input-telePrefix"><i class="fa fa-comment"></i> tele</label> <input type="text" id="node-input-telePrefix" placeholder="Telemetry topic prefix (Default: tele)"> </div> <div class="form-row"> <label for="node-input-qos"><i class="fa fa-empire"></i> QoS</label> <select id="node-input-qos" style="width:120px !important"> <option value="" selected disabled hidden>1</option> <option value="0">0</option> <option value="1">1</option> <option value="2">2</option> </select> &nbsp;&nbsp;<i class="fa fa-history"></i>&nbsp;Retain &nbsp; <select id="node-input-retain" style="width:120px !important"> <option value="" selected disabled hidden>false</option> <option value="false">false</option> <option value="true">true</option> </select> </div> </div> </div> </script> <script type="text/html" data-help-name="Tasmota Sensor"> <p>Connect a <b>Sensor</b> device running the <b>Tasmota</b> firmware.</p> <h3>Inputs</h3> <dl class="message-properties"> <dt>payload <span class="property-type">any</span></dt> <dd>any input received will trigger a sensor data request to the device.</dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>payload <span class="property-type">object</span></dt> <dd>the complete JSON object as received from the Tasmota device. Unless you have configured outputs using JSONata expressions.</dd> </dl> <h3>Details</h3> <p>This node read sensors data from the device.<p> <p>To combine more functionality from the same device (switch, sensor, etc..) use more than one node connected to the same device.</p> <p>Values are published as output on every telemetry messagge received from the device. </p> <p>Number of outputs can be configured, for each channel an expression must be given and is used to extract a piece of value, ex: <code>AM2301.Temperature</code>. Complex objects can also be created using JSONata expressions.<p> <p>Any messagge received in input will trigger a fresh-value-request to the device, thus you can easily attach a repeating injection to receive the sensor data at an higher frequency than the normal Tasmota telemetry configuration.</p> <p>In the Avanced tab you can customize the topic format for special cases, the default values should work for a default Tasmota installation.</p> <p>Input messagges are NOT forwarded to the output.</p> </script> <script type="text/javascript"> RED.nodes.registerType("Tasmota Sensor", { category: "tasmota", color: "#28AFB0", defaults: { // common basic broker: { type: "tasmota-mqtt-broker", required: true }, device: { value: "", required: true }, name: { value: "" }, outputs: { value: 1 }, uidisabler: { value: false }, // common advanced fullTopic: { value: "" }, cmndPrefix: { value: "" }, statPrefix: { value: "" }, telePrefix: { value: "" }, qos: { value: "1" }, // NOTE: always stored as string retain: { value: "false" }, // NOTE: always stored as string // node specific rules: { value:[] }, outputTopic: { value: "" } }, icon: "contrib-tasmota-sensor.svg", paletteLabel: 'sensor', inputs: 1, outputs: 1, label: function() { return this.name || this.device || "Tasmota Sensor" }, labelStyle: function() { return this.name ? "node_label_italic" : "" }, outputLabels: function(index) { if (this.outputs && this.outputs > 1) { return 'Output ' + (index+1) } }, oneditprepare: function () { // initialize tabs let tabs = RED.tabs.create({ id: "node-input-tasmota-tabs", onchange: function (tab) { $("#node-input-tabs-content").children().hide() $("#" + tab.id).show() } }) // populate tabs tabs.addTab({ id: "tasmota-settings-tab", label: "Settings" }) tabs.addTab({ id: "tasmota-advanced-tab", label: "Advanced" }) // initialize editable list $("#node-input-rule-container").css('min-height','250px').editableList({ sortable: true, removable: true, addItem: function(container, i, opt) { const rule = opt.r const row = $('<div/>').appendTo(container) const tinput = $('<input/>', {class:"node-input-rule-exp-value", type:"text", style:"width:90%;"}) .val(rule).appendTo(row) .typedInput({default:'jsonata', types:['jsonata']}) const finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row) finalspan.append(' &#8594; <span class="node-input-rule-index">'+(i+1)+'</span> ') }, sortItems: function(rules) { const items = $("#node-input-rule-container").editableList('items') items.each(function(i) { $(this).find(".node-input-rule-index").html(i + 1) }) }, removeItem: function(opt) { const items = $("#node-input-rule-container").editableList('items') items.each(function(i) { $(this).find(".node-input-rule-index").html(i + 1) }) }, }) // populate editable list for (let i = 0; i < this.rules.length; i++) { const rule = this.rules[i] $("#node-input-rule-container").editableList('addItem', {r: rule, i: i}) } }, oneditsave: function() { const items = $("#node-input-rule-container").editableList('items') const node = this node.rules = [] items.each(function(i) { const rule = $(this).find(".node-input-rule-exp-value").typedInput('value') node.rules.push(rule) }) $('#node-input-outputs').val(node.rules.length || 1) } }) </script>