UNPKG

node-red-contrib-dali-sensor

Version:

Node-RED node for parsing DALI sensor data and outputting motion and lux

128 lines (115 loc) 5.29 kB
<script type="text/javascript"> RED.nodes.registerType('dali-sensor', { category: 'input', color: '#a4a4a4', defaults: { name: { value: '' }, shortAddress: { value: '1', required: true }, motionInstance: { value: 0, required: false, validate: RED.validators.number() }, luxInstance: { value: 1, required: false, validate: RED.validators.number() }, luxSetpoint: { value: 400, required: true, validate: RED.validators.number() }, useBoolean: { value: true }, /* new */ enableAutoOff: { value: false }, autoOffDelaySec: { value: 30, validate: v => !isNaN(v) && Number(v) > 0 } }, inputs: 1, outputs: 3, outputLabels: ['Motion','Lux Value','Lux Alarm'], icon: 'sensor.png', label: function() { var addr = this.shortAddress || '?'; var base = this.name || 'DALI Sensor'; return base + ' [' + addr + ']'; }, oneditprepare: function() { var node = this; $('#node-input-name').val(node.name); $('#node-input-shortAddress').val(node.shortAddress); $('#node-input-motionInstance').val(node.motionInstance); $('#node-input-luxInstance').val(node.luxInstance); $('#node-input-luxSetpoint').val(node.luxSetpoint); $('#node-input-useBoolean').prop('checked', node.useBoolean); // ---- Auto Off UI wiring const $chk = $('#node-input-enableAutoOff'); const $delay = $('#node-input-autoOffDelaySec'); if ($delay.val() === '' || $delay.val() == null) $delay.val(30); function syncAutoOffUI() { const on = !!$chk.prop('checked'); $delay.prop('disabled', !on); $('#autooff-help').toggle(on); // show short hint only when active } $chk.on('change', syncAutoOffUI); syncAutoOffUI(); } }); </script> <script type="text/html" data-template-name="dali-sensor"> <style> /* tiny helper styles to align checkboxes & inputs neatly */ .af-inline { display:flex; align-items:center; gap:8px; flex-wrap:wrap; } .af-inline .units { color:#888; } .muted { color:#888; font-size:11px; } .w-100 { width:100%; } .w-8rem { width:8rem; } .no-wrap { white-space:nowrap; } </style> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> Name</label> <input type="text" id="node-input-name" class="w-100"/> </div> <div class="form-row"> <label for="node-input-shortAddress"><i class="fa fa-hashtag"></i> Short Address</label> <input type="text" id="node-input-shortAddress" class="w-8rem"/> </div> <div class="form-row"> <label for="node-input-motionInstance"><i class="fa fa-arrows-alt"></i> Motion Instance</label> <input type="number" id="node-input-motionInstance" class="w-8rem"/> </div> <div class="form-row"> <label for="node-input-luxInstance"><i class="fa fa-sun-o"></i> Lux Instance</label> <input type="number" id="node-input-luxInstance" class="w-8rem"/> </div> <div class="form-row"> <label for="node-input-luxSetpoint"><i class="fa fa-adjust"></i> Lux Setpoint</label> <input type="number" id="node-input-luxSetpoint" class="w-8rem"/> </div> <div class="form-row"> <label for="node-input-useBoolean"><i class="fa fa-toggle-off"></i> Use Boolean</label> <div class="af-inline"> <input type="checkbox" id="node-input-useBoolean"> <span class="muted">Output <code>true/false</code> instead of <code>On/Off</code></span> </div> </div> <!-- Auto Off: single tidy row with checkbox + timeout + units --> <div class="form-row"> <label for="node-input-enableAutoOff"><i class="fa fa-clock-o"></i> Auto Off</label> <div class="af-inline"> <input type="checkbox" id="node-input-enableAutoOff"> <input type="number" id="node-input-autoOffDelaySec" min="1" step="1" class="w-8rem"> <span class="units no-wrap">seconds</span> <span id="autooff-help" class="muted">On immediately / Off after delay (non-resettable)</span> </div> </div> </script> <script type="text/html" data-help-name="dali-sensor"> <p>This node parses DALI sensor frames (Device or Device/Instance schemes) and outputs:</p> <ul> <li><b>Motion</b>: latched occupancy state (On/Off or true/false)</li> <li><b>Lux Value</b>: raw integer lux reading</li> <li><b>Lux Alarm</b>: whether lux &lt; setpoint (On/Off or true/false)</li> </ul> <p>Configure:</p> <ul> <li><code>shortAddress</code> to filter your device</li> <li><code>motionInstance</code> &amp; <code>luxInstance</code> numbers to map instances (Instance scheme) or types (Device scheme)</li> <li><code>luxSetpoint</code> threshold</li> <li><code>useBoolean</code> to switch outputs between boolean or "On"/"Off"</li> </ul> <h3>Auto Off (optional)</h3> <ul> <li>Motion output turns <b>On immediately</b> and <b>Off after the configured delay</b> (non-resettable).</li> <li>Additional Off frames do not extend the countdown; an On cancels it.</li> <li><code>msg.delay</code> (ms) can override the timeout when the countdown starts.</li> </ul> </script>