UNPKG

node-red-contrib-huawei-solar

Version:

Node-RED nodes for reading data from Huawei SmartLogger 3000 and SUN2000 inverters via Modbus TCP

220 lines (189 loc) 11.3 kB
<script type="text/javascript"> RED.nodes.registerType('sun2000', { category: 'input', color: '#ffcc66', defaults: { name: { value: "" }, host: { value: "", required: true, validate: RED.validators.regex(/^[a-zA-Z0-9.-]+$/) }, port: { value: 502, required: true, validate: RED.validators.number() }, inverterAddress: { value: 12, required: true, validate: RED.validators.number() }, useCustomName: { value: false }, deviceName: { value: "" }, dataDevice: { value: false }, dataPower: { value: true }, dataVoltages: { value: false }, dataCurrents: { value: false }, dataStrings: { value: false }, dataStatus: { value: false }, dataAlarms: { value: false }, alwaysIncludeAlarmTexts: { value: false }, namingConvention: { value: "descriptive", required: true }, timeout: { value: 5000, validate: RED.validators.number() }, retries: { value: 3, validate: RED.validators.number() }, continueOnFail: { value: false }, splitOutputs: { value: false }, outputs: { value: 1 } }, inputs: 1, outputs: 1, icon: "icons/sun2000.svg", label: function() { return this.name || ("SUN2000-" + (this.inverterAddress || "12")); }, oneditprepare: function() { // Initialize outputs field $("#node-input-outputs").val(this.outputs || 1); // Handle split outputs toggle $("#node-input-splitOutputs").change(function() { $("#node-input-outputs").val($(this).is(':checked') ? 2 : 1); }); // Set up custom name toggle $("#node-input-useCustomName").change(function() { if ($(this).is(':checked')) { $(".form-row-custom-name").show(); } else { $(".form-row-custom-name").hide(); } }); // Trigger initial changes $("#node-input-useCustomName").trigger('change'); $("#node-input-splitOutputs").trigger('change'); }, oneditsave: function() { // Update outputs based on splitOutputs checkbox $("#node-input-outputs").val($("#node-input-splitOutputs").is(':checked') ? 2 : 1); } }); </script> <script type="text/html" data-template-name="sun2000"> <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-host"><i class="fa fa-server"></i> Host</label> <input type="text" id="node-input-host" placeholder="SmartLogger IP address"> </div> <div class="form-row"> <label for="node-input-port"><i class="fa fa-plug"></i> Port</label> <input type="number" id="node-input-port" placeholder="502" min="1" max="65535"> </div> <div class="form-row"> <label for="node-input-inverterAddress"><i class="fa fa-hashtag"></i> Inverter Address</label> <input type="number" id="node-input-inverterAddress" placeholder="12" min="1" max="247"> <div class="form-tips">Modbus unit ID of the specific inverter to read</div> </div> <div class="form-row"> <input type="checkbox" id="node-input-useCustomName" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-useCustomName" style="width: auto; margin-left: 5px;">Use Custom Name</label> </div> <div class="form-row form-row-custom-name" style="display:none; margin-left: 20px;"> <label for="node-input-deviceName"><i class="fa fa-edit"></i> Device Name</label> <input type="text" id="node-input-deviceName" placeholder="East Roof Array"> </div> <div class="form-row"> <label><i class="fa fa-list"></i> Data Categories</label> <div style="margin-left: 20px;"> <input type="checkbox" id="node-input-dataDevice" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-dataDevice" style="width: auto; margin-left: 5px; margin-right: 20px;">Device Information</label> <input type="checkbox" id="node-input-dataPower" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-dataPower" style="width: auto; margin-left: 5px; margin-right: 20px;">Power & Energy</label><br style="margin-bottom: 5px;"> <input type="checkbox" id="node-input-dataVoltages" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-dataVoltages" style="width: auto; margin-left: 5px; margin-right: 20px;">Grid Voltages</label> <input type="checkbox" id="node-input-dataCurrents" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-dataCurrents" style="width: auto; margin-left: 5px; margin-right: 20px;">Grid Currents</label><br style="margin-bottom: 5px;"> <input type="checkbox" id="node-input-dataStrings" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-dataStrings" style="width: auto; margin-left: 5px; margin-right: 20px;">PV String Data</label> <input type="checkbox" id="node-input-dataStatus" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-dataStatus" style="width: auto; margin-left: 5px; margin-right: 20px;">Status & Temperature</label><br style="margin-bottom: 5px;"> <input type="checkbox" id="node-input-dataAlarms" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-dataAlarms" style="width: auto; margin-left: 5px;">Alarms & Faults</label> </div> </div> <div class="form-row"> <input type="checkbox" id="node-input-alwaysIncludeAlarmTexts" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-alwaysIncludeAlarmTexts" style="width: 70%;"> Always Include Alarm Texts</label> <div class="form-tips">Include alarmTexts field in output even when empty</div> </div> <div class="form-row"> <label for="node-input-namingConvention"><i class="fa fa-font"></i> Field Naming</label> <select id="node-input-namingConvention" style="width:70%;"> <option value="descriptive">Descriptive (activePower, phaseAVoltage)</option> <option value="iec61850">IEC 61850 (P, Ua)</option> </select> </div> <div class="form-row"> <label for="node-input-timeout"><i class="fa fa-clock-o"></i> Timeout (ms)</label> <input type="number" id="node-input-timeout" placeholder="5000" min="1000"> </div> <div class="form-row"> <label for="node-input-retries"><i class="fa fa-refresh"></i> Retries</label> <input type="number" id="node-input-retries" placeholder="3" min="0"> </div> <div class="form-row"> <input type="checkbox" id="node-input-continueOnFail" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-continueOnFail" style="width: 70%;"> Continue on fail</label> <div class="form-tips">Send error information as output instead of raising an error</div> </div> <div class="form-row"> <input type="checkbox" id="node-input-splitOutputs" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-splitOutputs" style="width: 70%;"> Split telemetry and status outputs</label> <div class="form-tips">Send telemetry data to output 1 and status data to output 2</div> </div> <input type="hidden" id="node-input-outputs"/> </script> <script type="text/html" data-help-name="sun2000"> <p>Reads detailed data from a single Huawei SUN2000 inverter via Modbus TCP through a SmartLogger gateway.</p> <h3>Configuration</h3> <p><strong>Connection:</strong> Configure the SmartLogger IP address, port (typically 502), and the specific inverter address to read.</p> <p><strong>Inverter Address:</strong> The Modbus unit ID of the inverter (typically 12, 13, 14, 15, etc.).</p> <p><strong>Data Categories:</strong> Select which types of data to read using checkboxes:</p> <ul> <li><strong>Device Information:</strong> Model, serial number, firmware version, specifications</li> <li><strong>Power & Energy:</strong> Real-time power, daily/total energy, efficiency</li> <li><strong>Grid Voltages:</strong> Line and phase voltages (UAB, UBC, UCA, Ua, Ub, Uc)</li> <li><strong>Grid Currents:</strong> Phase currents and frequency</li> <li><strong>PV String Data:</strong> Individual string voltages, currents, and power</li> <li><strong>Status & Temperature:</strong> Device status, temperatures, insulation resistance</li> <li><strong>Alarms & Faults:</strong> Comprehensive alarm decoding with readable messages</li> </ul> <p><strong>Field Naming:</strong> Choose between descriptive names (activePower) or IEC 61850 standard (P).</p> <h3>Inputs</h3> <dl class="message-properties"> <dt>msg <span class="property-type">object</span></dt> <dd>Any input message triggers data reading. The payload is ignored.</dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>payload <span class="property-type">object</span></dt> <dd> <p>Inverter data with nested structure:</p> <ul> <li><code>ts</code> - Timestamp</li> <li><code>unitId</code>, <code>deviceName</code> - Device identification</li> <li><code>telemetry</code> - Power, voltage, current, and energy data</li> <li><code>status</code> - Device status, temperatures, alarms</li> </ul> <p>If reading fails, an error message is sent instead.</p> </dd> </dl> <h3>Usage</h3> <p><strong>One node per inverter:</strong> Deploy separate SUN2000 nodes for each inverter you want to monitor.</p> <p><strong>Modular design:</strong> Each node handles one inverter, making it easy to scale and manage.</p> <p><strong>Flexible data:</strong> Choose exactly which data categories you need for each inverter.</p> </script> <style> .form-row-manual, .form-row-discovery { margin-left: 20px; border-left: 3px solid #ddd; padding-left: 10px; } .form-row-custom-names { margin-left: 40px; border-left: 2px solid #ccc; padding-left: 10px; } .mapping-row { margin-bottom: 5px; } </style>