Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. ioBroker Allgemein
    4. Huawei Sun2000 & ioBroker via JS script funktioniert

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Huawei Sun2000 & ioBroker via JS script funktioniert

    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      Thomas42 @WILHER last edited by

      @wilher Hi,
      wäre eventuell hifreich, wenn Du Dein Log posten würdest und nicht das Script 🙂

      1 Reply Last reply Reply Quote 0
      • Z
        zoid1988 @oswibz last edited by

        @oswibz

        Leider gibt es hier bei mir nichts neues ... Es funktioniert immer noch nicht ...

        1 Reply Last reply Reply Quote 0
        • Alex Warkentin
          Alex Warkentin last edited by

          Ich habe das Script gerade erfolgreich eingerichtet. War nicht ganz so einfach. Daher hier noch ein paar Tipps:

          Javascript Adapter und Nodejs sollten auf dem neuesten Stand sein, oder zumindest zueinander passen.

          In den Einstellungen des Javascript-Adapters muss die Erweiterung "modbus-serial" eingetragen werden (einfach reinschreiben und bestätigen). Bei mir meckert das Script danach trotzdem über die Zeile, funktioniert aber.

          Die IP eures Dongles muss eingetragen werden (ohne $$$)

          // Enter your inverter modbus IP and port here:
          client.connectTCP("192.xxx.xxx.xxx", { port: 502 });
          

          Die IDs des WRs und der Batterien könnt ihr im Gerätemanagement in der Fusionsolar Web-Oberfläche herausfinden, oder direkt am Gerät. Dafür braucht ihr aber den Installateur-Zugang. Normalerweise hat der WR aber die ID 1 und der SmartMeter die 0. Bei der Batterie kann ich nicht weiterhelfen. Habe keine.

          // Enter the Modbus-IDs of your Sun2000 inverters here:
          const modBusIDs = [1];
          // On which Modbus-ID can we reach the power meter? (via Sun2000!)
          const powerMeterID = 0;
          

          Die existState Funktion ist fehlerhaft, da objectname nicht den vollen Pfad beinhaltet. So funktioniert es:

          if(!existsState("javascript.0." + objectname))
          

          Bei der Start- und Stopzeit habe ich die Sekunden in Datum umgewandelt. Bitte auf Groß-Kleinschreibung achten

          ForceSetState("Solarpower.Huawei.Inverter." + id + ".StartupTime",              new Date(GetU32(globalDataBuffer[id-1], 32091)*1000),          {name: "", unit: ""});
          ForceSetState("Solarpower.Huawei.Inverter." + id + ".ShutdownTime",             new Date(GetU32(globalDataBuffer[id-1], 32093)*1000),          {name: "", unit: ""});
          
          S 1 Reply Last reply Reply Quote 0
          • S
            striegel26 @Alex Warkentin last edited by striegel26

            Hallo zusammen

            ich brauche mal eure Hilfe. Das Script scheint soweit zu funktionieren, aber es werden leider die Werte des PowerMeters nicht aktualisiert, das erste mal hat es funktioniert. Was habe ich falsch gemacht ?

            VG Dennis

            // License: Beerware! Do what ever you like with this, but I'm not liable for anything that you do with it.
            // If you like this code, feel free to buy me a beer ...
            // Have fun with it! der Kachel
            var ModbusRTU = require("modbus-serial");
            var client = new ModbusRTU();
            
            var modbusErrorMessages = [
                "Unknown error",
                "Illegal function (device does not support this read/write function)",
                "Illegal data address (register not supported by device)",
                "Illegal data value (value cannot be written to this register)",
                "Slave device failure (device reports internal error)",
                "Acknowledge (requested data will be available later)",
                "Slave device busy (retry request again later)"
            ];
            
            // open connection to a tcp line
            client.setTimeout(10000);
            
            // Enter your inverter modbus IP and port here:
            client.connectTCP("192.168.178.95", { port: 502 });
            // Enter the Modbus-IDs of your Sun2000 inverters here:
            const ModBusIDs = [16, 1];
            // On which Modbus-ID can we reach the power meter? (via Sun2000!)
            const PowerMeterID = 11;
            // Enter your battery stack setup. 2 dimensional array. 
            // e.g. [[3, 2], [3, 0]] means:
            // First inverter has two battery stacks with 3 + 2 battery modules
            // while second inverter has only one battery stack with 3 battery modules
            const BatteryUnits = [[3, 0], [3, 0]];
            
            // These register spaces need to be read:
            const RegisterSpacesToReadContinuously = [[30000, 81], [37100, 114], [32000, 116], [37000, 68],  [37700, 100], [37800, 100], [38200, 100], [38300, 100], [38400, 100], [35300, 40]];
            var RegisterSpacesToReadContinuouslyPtr = 0;
            
            var GlobalDataBuffer = new Array(2);
            for(var i=0; i<ModBusIDs.length; i++) {
                GlobalDataBuffer[i] = new Array(50000); // not optimized....
            }
            
            // ---------------------------------------------------------------
            // Some helper functions:
            function readUnsignedInt16(array) {
                var value = array[0];    
                return value;
            }
            
            function readUnsignedInt32(array) {
                var value = array[0] * 256 * 256 + array[1];    
                return value;
            }
            
            function readSignedInt16(array) {
                var value = 0;
                if (array[0] > 32767)
                    value = array[0] - 65535; 
                else
                    value = array[0];
            
                return value;
            }
            function readSignedInt32(array) {
                var value = 0;
                for (var i = 0; i < 2; i++) {
                    value = (value << 16) | array[i];
                }
                return value;
            }
            function getU16(dataarray, index) {
                var value = readUnsignedInt16(dataarray.slice(index, index+1));
                return value;
            }
            
            function getU32(dataarray, index) {
                var value = readUnsignedInt32(dataarray.slice(index, index+2));
                return value;
            }
            
            function getI16(dataarray, index) {
                var value = readSignedInt16(dataarray.slice(index, index+1));
                return value;
            }
            
            function getI32(dataarray, index) {
                var value = readSignedInt32(dataarray.slice(index, index+2));
                return value;
            }
            
            function getString(dataarray, index, length) {
                var shortarray = dataarray.slice(index, index+length);
                var bytearray = [];
                for(var i = 0; i < length; i++) {
                    bytearray.push(dataarray[index+i] >> 8);
                    bytearray.push(dataarray[index+i] & 0xff);
                }       
                var value =  String.fromCharCode.apply(null, bytearray);    
                return value;
            }
            
            function getZeroTerminatedString(dataarray, index, length) {
                var shortarray = dataarray.slice(index, index+length);
                var bytearray = [];
                for(var i = 0; i < length; i++) {
                    bytearray.push(dataarray[index+i] >> 8);
                    bytearray.push(dataarray[index+i] & 0xff);
                }       
                var value =  String.fromCharCode.apply(null, bytearray);    
                var value2 = new String(value).trim();
                return value2;
            }
            
            function forcesetState(objectname, value, options) {
                if(!existsState("javascript.0." + objectname)) {
                    createState(objectname, value, options); 
                    console.log("createstate " +  objectname + " to value " + value);            
                }
                    setState(objectname, value);
                }
            // ---------------------------------------------------------------
            // Functions to map registers into ioBreaker objects:
            function processOptimizers(id) {
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".OptimizerTotalNumber",     getU16(GlobalDataBuffer[id-1], 35200), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".OptimizerOnlineNumber",    getU16(GlobalDataBuffer[id-1], 35201), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".OptimizerFeatureData",     getU16(GlobalDataBuffer[id-1], 35202), {name: "", unit: ""});
            }
            
            function processInverterPowerAdjustments(id) {
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementMode",     getU16(GlobalDataBuffer[id-1], 35300), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementValue",    getU32(GlobalDataBuffer[id-1], 35301), {name: "", unit: ""}); // Note: This might be an error in the manual. It says register 35302 with quantity 2, but on 35303 is already the next value.
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementCommand",  getU16(GlobalDataBuffer[id-1], 35303), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementMode",   getU16(GlobalDataBuffer[id-1], 35304), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementValue",  getU32(GlobalDataBuffer[id-1], 35305), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementCommand",getU16(GlobalDataBuffer[id-1], 35307), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ActiveAdjustement.PowerMeterActivePower",     getI32(GlobalDataBuffer[id-1], 35313), {name: "", unit: ""});
            }
            
            function processBattery(id) {
                // Battery registers 1-15 (Stack 1 related)
                if(BatteryUnits[id-1][0] > 0) {
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.RunningStatus",          getU16(GlobalDataBuffer[id-1], 37000), {name: "", unit: ""});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.ChargeAndDischargePower",getI32(GlobalDataBuffer[id-1], 37001), {name: "Charge and Discharge Power", unit: "W"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.BusVoltage",             getU16(GlobalDataBuffer[id-1], 37003) / 10, {name: "Busvoltage", unit: "V"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.BatterySOC",             getU16(GlobalDataBuffer[id-1], 37004) / 10, {name: "Battery SOC", unit: "%"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.WorkingMode",            getU16(GlobalDataBuffer[id-1], 37006), {name: "Working Mode", unit: ""});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.RatedChargePower",       getU32(GlobalDataBuffer[id-1], 37007), {name: "", unit: "W"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.RatedDischargePower",    getU32(GlobalDataBuffer[id-1], 37009), {name: "", unit: "W"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.FaultID",                getU16(GlobalDataBuffer[id-1], 37014), {name: "", unit: ""});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayChargeCapacity",    getU32(GlobalDataBuffer[id-1], 37015) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37017) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.BusCurrent",             getI16(GlobalDataBuffer[id-1], 37021) / 10, {name: "Buscurrent", unit: "A"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.BatteryTemperature",     getI16(GlobalDataBuffer[id-1], 37022) / 10, {name: "Battery Temperatue", unit: "°C"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.RemainingChargeDischargeTime", getU16(GlobalDataBuffer[id-1], 37025), {name: "", unit: "mins"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.DCDCversion",            getZeroTerminatedString(GlobalDataBuffer[id-1], 37026, 10), {name: "", unit: ""});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.BMSversion",             getZeroTerminatedString(GlobalDataBuffer[id-1], 37036, 10), {name: "", unit: ""});
                }
                // Battery registers 16+17 (Storage-related)
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.MaximumChargePower",                getU32(GlobalDataBuffer[id-1], 37046), {name: "", unit: "W"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.MaximumDischargePower",             getU32(GlobalDataBuffer[id-1], 37048), {name: "", unit: "W"});
            
                // Battery register 18-20 (Stack 1 related)
                if(BatteryUnits[id-1][0] > 0) {
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.SN",                         getZeroTerminatedString(GlobalDataBuffer[id-1], 37052, 10), {name: "Serialnumber", unit: ""});       
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.TotalCharge",                getU32(GlobalDataBuffer[id-1], 37066) / 100, {name: "", unit: "kWh"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.TotalDischarge",             getU32(GlobalDataBuffer[id-1], 37068) / 100, {name: "", unit: "kWh"});
                }
                // Battery register 21-31 (Stack 2 related)
                if(BatteryUnits[id-1][1] > 0) {
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.SN",                     getZeroTerminatedString(GlobalDataBuffer[id-1], 37700, 10), {name: "Serialnumber", unit: ""});        
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.BatterySOC",             getU16(GlobalDataBuffer[id-1], 37738) / 10, {name: "", unit: "%"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.RunningStatus",          getU16(GlobalDataBuffer[id-1], 37741), {name: "", unit: ""});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.ChargeAndDischargePower",getI32(GlobalDataBuffer[id-1], 37743), {name: "", unit: "W"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayChargeCapacity",    getU32(GlobalDataBuffer[id-1], 37746) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37748) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.BusVoltage",             getU16(GlobalDataBuffer[id-1], 37750) / 10, {name: "", unit: "V"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.BusCurrent",             getI16(GlobalDataBuffer[id-1], 37751) / 10, {name: "", unit: "A"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.BatteryTemperature",     getI16(GlobalDataBuffer[id-1], 37752) / 10, {name: "", unit: "°C"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.TotalCharge",                 getU32(GlobalDataBuffer[id-1], 37753) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.TotalDischarge",              getU32(GlobalDataBuffer[id-1], 37755) / 100, {name: "", unit: "kWh"});
                }
                // Battery register 32-41 (Storage related)
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.RatedCapacity", getU32(GlobalDataBuffer[id-1], 37758) / 1, {name: "", unit: "Wh"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.SOC", getU16(GlobalDataBuffer[id-1], 37760) / 10, {name: "", unit: "%"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.RunningStatus", getU16(GlobalDataBuffer[id-1], 37762) / 1, {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.BusVoltage", getU16(GlobalDataBuffer[id-1], 37763) / 10, {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.BusCurrent", getI16(GlobalDataBuffer[id-1], 37764) / 10, {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 37765) / 1, {name: "", unit: "W"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.TotalCharge", getU32(GlobalDataBuffer[id-1], 37780) / 100, {name: "", unit: "kWh"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.TotalDischarge", getU32(GlobalDataBuffer[id-1], 37782) / 100, {name: "", unit: "kWh"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.CurrentDayChargeCapacity", getU32(GlobalDataBuffer[id-1], 37784) / 100, {name: "", unit: "kWh"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Battery.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37786) / 100, {name: "Current DayDiscarge ", unit: "kWh"});
            
                // Battery registers 42+43 (Battery stack related)   
                if(BatteryUnits[id-1][1] > 0) {
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.2.SoftwareVersion",    getZeroTerminatedString(GlobalDataBuffer[id-1], 37814, 8), {name: "Softwareversion", unit: ""});
                }
                if(BatteryUnits[id-1][0] > 0) {
                    forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack.1.SoftwareVersion",    getZeroTerminatedString(GlobalDataBuffer[id-1], 37799, 8), {name: "Softwareversion", unit: ""});
                }
            
                // Registers 44 to 98: (Battery pack related)
                for(var i = 1; i <= 2; i++){        
                    if(BatteryUnits[id-1][i-1] >= 0) {            
                        for(var j = 1; j <= BatteryUnits[id-1][i-1]; j++) {
                            //[[38200, 38242, 38284] [38326, 38368, 38410]]; (+42 for each battery pack, +126 for each stack)
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".SN",                getZeroTerminatedString(GlobalDataBuffer[id-1], 38200+(i-1)*126+(j-1)*42, 6), {name: "", unit: ""});
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".FirmwareVersion",   getZeroTerminatedString(GlobalDataBuffer[id-1], 38210+(i-1)*126+(j-1)*42, 8), {name: "", unit: ""});
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".WorkingStatus",     getU16(GlobalDataBuffer[id-1], 38228+(i-1)*126+(j-1)*42), {name: "", unit: ""});
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".BatterySOC",        getU16(GlobalDataBuffer[id-1], 38229+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "%"});
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 38233+(i-1)*126+(j-1)*42) / 1000, {name: "", unit: "kW"});
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Voltage",           getU16(GlobalDataBuffer[id-1], 38235+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "V"});
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Current",           getI16(GlobalDataBuffer[id-1], 38236+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "A"});
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".TotalCharge",       getU32(GlobalDataBuffer[id-1], 38238+(i-1)*126+(j-1)*42) / 100, {name: "", unit: "kWh"});
                            forcesetState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".TotalDischarge",    getU32(GlobalDataBuffer[id-1], 38240+(i-1)*126+(j-1)*42) / 100, {name: "", unit: "kWh"});
            
                            // [[38452, 38454, 38456][38458, 38460, 38462]] ( +2 for each pack, +6 for each stack)
                            createState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".MaxTemperature", getI16(GlobalDataBuffer[id-1], 38452+(i-1)*6+(j-1)*2) / 10, {name: "", unit: "°C"});
                            createState("Solarpower2.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".MinTemperature", getI16(GlobalDataBuffer[id-1], 38453+(i-1)*6+(j-1)*2) / 10, {name: "", unit: "°C"});
                        }
                    }        
                }
            
                // Battery registers 110-141 are not supported by this script yet!
            }
            
            function ProcessPowerMeterStatus() {       
                forcesetState("Solarpower2.Huawei.Meter.Status",          getU16(GlobalDataBuffer[PowerMeterID], 37100), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Meter.VoltageL1",        getI32(GlobalDataBuffer[PowerMeterID], 37101)  / 10, {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Meter.VoltageL2",        getI32(GlobalDataBuffer[PowerMeterID], 37103)  / 10, {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Meter.VoltageL3",        getI32(GlobalDataBuffer[PowerMeterID], 37105)  / 10, {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Meter.CurrentL1",        getI32(GlobalDataBuffer[PowerMeterID], 37107)  / 100, {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Meter.CurrentL2",        getI32(GlobalDataBuffer[PowerMeterID], 37109)  / 100, {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Meter.CurrentL3",        getI32(GlobalDataBuffer[PowerMeterID], 37111) / 100, {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Meter.ActivePower",     getI32(GlobalDataBuffer[PowerMeterID], 37113) / 1, {name: "", unit: "W"});
                forcesetState("Solarpower2.Huawei.Meter.ReactivePower",   getI32(GlobalDataBuffer[PowerMeterID], 37115) / 1, {name: "", unit: "Var"});
                forcesetState("Solarpower2.Huawei.Meter.PowerFactor",     getI16(GlobalDataBuffer[PowerMeterID], 37117) / 1000, {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Meter.GridFrequency",   getI16(GlobalDataBuffer[PowerMeterID], 37118) / 100, {name: "", unit: "Hz"});
                forcesetState("Solarpower2.Huawei.Meter.PositiveActiveEnergy",     getI32(GlobalDataBuffer[PowerMeterID], 37119) / 100, {name: "", unit: "kWh"});
                forcesetState("Solarpower2.Huawei.Meter.ReverseActiveEnergy",      getI32(GlobalDataBuffer[PowerMeterID], 37121) / 100, {name: "", unit: "kWh"});
                forcesetState("Solarpower2.Huawei.Meter.AccumulatedReactivePower", getI32(GlobalDataBuffer[PowerMeterID], 37123) / 100, {name: "", unit: "kVarh"});
                forcesetState("Solarpower2.Huawei.Meter.MeterType",       getU16(GlobalDataBuffer[PowerMeterID], 37125), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Meter.VoltageL1-L2",       getI32(GlobalDataBuffer[PowerMeterID], 37126) / 10, {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Meter.VoltageL2-L3",       getI32(GlobalDataBuffer[PowerMeterID], 37128) / 10, {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Meter.VoltageL3-L1",       getI32(GlobalDataBuffer[PowerMeterID], 37130) / 10, {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Meter.ActivePowerL1",    getI32(GlobalDataBuffer[PowerMeterID], 37132) / 1, {name: "", unit: "W"});
                forcesetState("Solarpower2.Huawei.Meter.ActivePowerL2",    getI32(GlobalDataBuffer[PowerMeterID], 37134) / 1, {name: "", unit: "W"});
                forcesetState("Solarpower2.Huawei.Meter.ActivePowerL3",    getI32(GlobalDataBuffer[PowerMeterID], 37136) / 1, {name: "", unit: "W"});
                forcesetState("Solarpower2.Huawei.Meter.MeterModel",      getU16(GlobalDataBuffer[PowerMeterID], 37138), {name: "", unit: ""});
            }
            
            function processInverterStatus(id) {
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".State1", getU16(GlobalDataBuffer[id-1], 32000), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".State2", getU16(GlobalDataBuffer[id-1], 32001), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".State3", getU16(GlobalDataBuffer[id-1], 32002), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Alarm1", getU16(GlobalDataBuffer[id-1], 32008), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Alarm2", getU16(GlobalDataBuffer[id-1], 32009), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Alarm3", getU16(GlobalDataBuffer[id-1], 32010), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".String.1_Voltage",       getI16(GlobalDataBuffer[id-1], 32016) / 10  , {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".String.1_Current",       getI16(GlobalDataBuffer[id-1], 32017) / 100 , {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".String.2_Voltage",       getI16(GlobalDataBuffer[id-1], 32018) / 10  , {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".String.2_Current",       getI16(GlobalDataBuffer[id-1], 32019) / 100 , {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".InputPower",             getI32(GlobalDataBuffer[id-1], 32064) / 1000, {name: "", unit: "kW"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L1-L2_Voltage",           getU16(GlobalDataBuffer[id-1], 32066) / 10  , {name: "", unit: "V"});      
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L2-L3_Voltage",           getU16(GlobalDataBuffer[id-1], 32067) / 10  , {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L3-L1_Voltage",           getU16(GlobalDataBuffer[id-1], 32068) / 10  , {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L1_Voltage",            getU16(GlobalDataBuffer[id-1], 32069) / 10  , {name: "", unit: "V"});                              
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L2_Voltage",            getU16(GlobalDataBuffer[id-1], 32070) / 10  , {name: "", unit: "V"});                                                  
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L3_Voltage",            getU16(GlobalDataBuffer[id-1], 32071) / 10  , {name: "", unit: "V"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L1_Current",         getI32(GlobalDataBuffer[id-1], 32072) / 1000, {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L2_Current",         getI32(GlobalDataBuffer[id-1], 32074) / 1000, {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Grid.L3_Current",         getI32(GlobalDataBuffer[id-1], 32076) / 1000, {name: "", unit: "A"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".PeakActivePowerDay",     getI32(GlobalDataBuffer[id-1], 32078) / 1000, {name: "", unit: "kW"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ActivePower",            getI32(GlobalDataBuffer[id-1], 32080) / 1000, {name: "", unit: "kW"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ReactivePower",          getI32(GlobalDataBuffer[id-1], 32082) / 1000, {name: "", unit: "kVar"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".PowerFactor",            getI16(GlobalDataBuffer[id-1], 32084) / 1000, {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".GridFrequency",          getU16(GlobalDataBuffer[id-1], 32085) / 100 , {name: "", unit: "Hz"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Efficiency",             getU16(GlobalDataBuffer[id-1], 32086) / 100 , {name: "", unit: "%"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".InternalTemperature",    getI16(GlobalDataBuffer[id-1], 32087) / 10  , {name: "", unit: "°C"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".InsulationResistance",   getU16(GlobalDataBuffer[id-1], 32088) / 1000, {name: "", unit: "MOhm"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".DeviceStatus",              getU16(GlobalDataBuffer[id-1], 32089), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".FaultCode",                 getU16(GlobalDataBuffer[id-1], 32090), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".StartupTime",               getU16(GlobalDataBuffer[id-1], 32091), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ShutdownTime",              getU16(GlobalDataBuffer[id-1], 32093), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".AccomulatedEnergyYield",    getU16(GlobalDataBuffer[id-1], 32106), {name: "", unit: "kWh"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".DailyEnergyYield",          getU16(GlobalDataBuffer[id-1], 32114), {name: "", unit: "kWh"});
            }
            
            function ProcessDeviceInfo(id) {      
                // Note: Manual says its quantitiy is 15, but that is the number (+1) of 8bit characters
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".Model",  getZeroTerminatedString(GlobalDataBuffer[id-1], 30000, 8), {name: "", unit: ""}); 
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".SN",     getZeroTerminatedString(GlobalDataBuffer[id-1], 30015, 6), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".PN",     getZeroTerminatedString(GlobalDataBuffer[id-1], 30025, 6), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".ModelID",           getU16(GlobalDataBuffer[id-1], 30070), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".PVStrings",         getU16(GlobalDataBuffer[id-1], 30071), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".MPPTrackers",       getU16(GlobalDataBuffer[id-1], 30072), {name: "", unit: ""});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".MaxRatedPower",     getU32(GlobalDataBuffer[id-1], 30073) / 1000, {name: "", unit: "kW"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".MaxActivePower",    getU32(GlobalDataBuffer[id-1], 30075) / 1000, {name: "", unit: "kW"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".MaxApparentPower",  getU32(GlobalDataBuffer[id-1], 30077) / 1000, {name: "", unit: "kVA"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".MaxReactivePowerToGrid",        getI32(GlobalDataBuffer[id-1], 30079) / 1000, {name: "", unit: "kVAr"});
                forcesetState("Solarpower2.Huawei.Inverter." + id + ".MaxReactivePowerFromGrid",      getI32(GlobalDataBuffer[id-1], 30081) / 1000, {name: "", unit: "kVAr"});
            }
            
            function readRegisterSpace(id, address, length) {
                client.setID(ModBusIDs[id-1]);
                client.readHoldingRegisters(address, length, function(err, data) {
                    if (err) {
                        console.warn("Error received reading address " + address + " from id: " + ModBusIDs[id-1] + " with error: " + modbusErrorMessages[err.modbusCode]);            
                    }
                    else
                    {   
                        console.debug("Read data from id/address " + ModBusIDs[id-1] + "/" + address + "\nData is: " + data.data);
                        for(var i = 0; i < length; i++)  {
                            GlobalDataBuffer[id-1][address+i] = data.data[i];
                        } 
                    }
                });
            }
            
            function processData() {
                console.log("Processing new data...");
                for(var i = 1; i <= ModBusIDs.length; i++) {
                    ProcessDeviceInfo(i);
                    processInverterStatus(i);
                    processBattery(i);
                    processInverterPowerAdjustments(i);
                    processOptimizers(i); 
                }    
                ProcessPowerMeterStatus();
                console.log("Processing done!");
            }
            
            
            // -------------------------------------------------------------------
            // This is the main function triggering a  read via modbus-tcp every two seconds.
            // Processing of data is triggered as soon as one complete set of registers is copied.
            var triggerprocessing = 0; 
            var currentinverter = 1;
            
            
            setInterval(function() {
                if(triggerprocessing == 1) {
                    triggerprocessing = 0;
                    processData();        
                }      
               
                console.log("Triggering read of inverter " + currentinverter + " at address " + RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0] + " with length " +  RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]);
                readRegisterSpace(currentinverter, RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0], RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]); 
                RegisterSpacesToReadContinuouslyPtr++;               
                if(RegisterSpacesToReadContinuouslyPtr >= RegisterSpacesToReadContinuously.length) {
                    RegisterSpacesToReadContinuouslyPtr = 0;
                    currentinverter++
                    if(currentinverter > ModBusIDs.length){
                        currentinverter = 1;  
                        triggerprocessing = 1;                    
                    }
                }     
            }, 2000);
            
            Alex Warkentin 1 Reply Last reply Reply Quote 0
            • Alex Warkentin
              Alex Warkentin @striegel26 last edited by

              @striegel26 Bist du sicher, dass dein Powermeter die ID 11 hat und hast du zwei Wechselrichter mit 16 und 1?

              Was sagen denn deine Protokolle?

              S 1 Reply Last reply Reply Quote 0
              • S
                striegel26 @Alex Warkentin last edited by striegel26

                @alex-warkentin ja mir kam das auch komisch vor mit der ID11 aber schau ...... oder verstehe ich da was falsch? WR mit 16 und 1 mein fehler 16 ist gelöscht natürlich.
                Meter.jpeg
                Log_PV.txt

                Alex Warkentin 1 Reply Last reply Reply Quote 0
                • Alex Warkentin
                  Alex Warkentin @striegel26 last edited by

                  @striegel26 Ich bin mir da nicht sicher. Bei mir steht dort auch die 11 drin, aber ich habe die 0 von Anfang an stehen gelassen und damit funktioniert es.

                  S 1 Reply Last reply Reply Quote 0
                  • S
                    striegel26 @Alex Warkentin last edited by

                    @alex-warkentin Oh man ja die 0 ist es !!! Danke dir 😊 Jetzt funktioniert alles

                    1 Reply Last reply Reply Quote 0
                    • J
                      juggi1962 last edited by

                      Hallo an alle Wissenden 🙂
                      Funktioniert dieses Skript auch ohne Speicher?
                      Ich hab leider keinen Speicher was muss ich dann daran ändern.
                      Für mich ist JS Neuland.
                      Wäre schön wenn mir jemand helfen könnte.
                      Danke im Voraus Gruß Jürgen.

                      
                      javascript.0
                      2023-03-05 09:56:27.826	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38200 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:25.826	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37800 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:23.824	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37700 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:21.826	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37000 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:19.823	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 32000 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:17.823	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37100 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:15.823	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 30000 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:13.821	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 35300 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:11.820	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38400 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:09.820	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38300 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:07.819	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38200 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:05.819	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37800 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:03.820	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37700 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:56:01.819	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37000 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:59.817	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 32000 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:57.817	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37100 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:55.817	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 30000 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:53.817	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 35300 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:51.818	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38400 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:49.816	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38300 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:47.816	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38200 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:45.815	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37800 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:43.815	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37700 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:41.815	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37000 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:39.815	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 32000 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:37.814	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37100 from id: undefined with error: undefined
                      
                      javascript.0
                      2023-03-05 09:55:35.814	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 30000 from id: undefined with error: undefined
                      
                      A Alex Warkentin 2 Replies Last reply Reply Quote 0
                      • A
                        ATARI @juggi1962 last edited by ATARI

                        @juggi1962

                        Bin auch nicht so fit in js..
                        ändere mal die Einstellung für den Speicher.

                        zum Bsp.:
                        const BatteryUnits = [0, 0];

                        Gruß
                        ATARI

                        Edit:
                        Deinem Log zufolge bekommst Du keine Daten von der Anlage.
                        Hast Du in den Kom.einstellung des Wechselrichters den ModBus
                        aktiviert?

                        J 1 Reply Last reply Reply Quote 0
                        • A
                          ATARI @Kachel last edited by ATARI

                          @kachel

                          Vielen Dank für das Script und Deine Arbeit !

                          Wie kann ich den Abfrage Intervall nach einem Durchlauf verzögern
                          oder nur einmal pro Minute oder alle 5 Minuten starten lassen?
                          Ein Timer mit: von Uhrzeit bis Uhrzeit alle x Minuten wäre auch super.

                          Momentan bekommt das Script irgendwann im Laufe des Tages keine
                          Daten mehr und erzeugt nur noch Fehlermeldungen.
                          In diesem Fall hilft nur: das Script stoppen und nach einigen Minuten
                          wieder starten.

                          Gruß
                          ATARI

                          Edit:
                          Würde Dir für Deine Arbeit 'nen Kaffee oder 'n Bier spendieren.

                          Alex Warkentin J H 3 Replies Last reply Reply Quote 0
                          • Alex Warkentin
                            Alex Warkentin @juggi1962 last edited by

                            @juggi1962
                            Der Fehler besagt, dass deine ID für den Wechselrichter "undefined" ist. Welche ID hast du im Script eingestellt und hast du sie mit deinen aktuellen Einstellungen abgeglichen?

                            J 1 Reply Last reply Reply Quote 0
                            • Alex Warkentin
                              Alex Warkentin @ATARI last edited by

                              @atari
                              Das Abfrageintervall kannst du in der letzten Zeile des Scripts in ms einstellen. Dein Problem liegt wohl aber weniger am Intervall (dann kommt zwischendurch eine Warnung, dass das Gerät beschäftigt ist), sondern, dass das Script beim Verlust der Modbus-Verbindung diese nicht wieder automatisch aufbaut.

                              J A 2 Replies Last reply Reply Quote 0
                              • J
                                juggi1962 @Alex Warkentin last edited by

                                @alex-warkentin
                                Danke für deine Antwort. Soweit funktioniert jetzt alles.
                                Gibt es eigentlich eine Möglichkeit die Infos auszuschalten denn so sehe ich im Log ja nur mehr diese von dem Skript.
                                Danke für eure Hilfe

                                Alex Warkentin 1 Reply Last reply Reply Quote 0
                                • J
                                  juggi1962 @ATARI last edited by

                                  @atari sagte in Huawei Sun2000 & ioBroker via JS script funktioniert:

                                  @juggi1962

                                  Bin auch nicht so fit in js..
                                  ändere mal die Einstellung für den Speicher.

                                  zum Bsp.:
                                  const BatteryUnits = [0, 0];

                                  Gruß
                                  ATARI

                                  Edit:
                                  Deinem Log zufolge bekommst Du keine Daten von der Anlage.
                                  Hast Du in den Kom.einstellung des Wechselrichters den ModBus
                                  aktiviert?

                                  Danke für deine Antwort. Soweit läuft jetzt alles

                                  1 Reply Last reply Reply Quote 0
                                  • Alex Warkentin
                                    Alex Warkentin @juggi1962 last edited by

                                    @juggi1962
                                    Suche mal im Script mit STRG + F nach "console.log" und setze überall, wo dich die Information nicht interessiert "//" vor die Zeile.

                                    J 1 Reply Last reply Reply Quote 0
                                    • J
                                      juggi1962 @Alex Warkentin last edited by

                                      @alex-warkentin
                                      Super Danke, werde ich gleich probieren

                                      1 Reply Last reply Reply Quote 0
                                      • J
                                        juggi1962 @ATARI last edited by

                                        @atari sagte in Huawei Sun2000 & ioBroker via JS script funktioniert:

                                        @kachel

                                        Vielen Dank für das Script und Deine Arbeit !

                                        Wie kann ich den Abfrage Intervall nach einem Durchlauf verzögern
                                        oder nur einmal pro Minute oder alle 5 Minuten starten lassen?
                                        Ein Timer mit: von Uhrzeit bis Uhrzeit alle x Minuten wäre auch super.

                                        Momentan bekommt das Script irgendwann im Laufe des Tages keine
                                        Daten mehr und erzeugt nur noch Fehlermeldungen.
                                        In diesem Fall hilft nur: das Script stoppen und nach einigen Minuten
                                        wieder starten.

                                        Gruß
                                        ATARI

                                        Edit:
                                        Würde Dir für Deine Arbeit 'nen Kaffee oder 'n Bier spendieren.

                                        Ich habe leider das selbe Problem. Eine Weile läuft alles bestens und dann nur mehr Fehler.
                                        Neustart und es läuft wieder ein Weilchen.

                                        1 Reply Last reply Reply Quote 0
                                        • J
                                          juggi1962 @Alex Warkentin last edited by

                                          @alex-warkentin sagte in Huawei Sun2000 & ioBroker via JS script funktioniert:

                                          @atari
                                          Das Abfrageintervall kannst du in der letzten Zeile des Scripts in ms einstellen. Dein Problem liegt wohl aber weniger am Intervall (dann kommt zwischendurch eine Warnung, dass das Gerät beschäftigt ist), sondern, dass das Script beim Verlust der Modbus-Verbindung diese nicht wieder automatisch aufbaut.

                                          Ich habe das selbe Problem.
                                          Ich habe eine LAN Verbindung also sollte fie Verbindung bleiben, oder verstehe ich da was falsch? was kann man da machen

                                          Alex Warkentin 1 Reply Last reply Reply Quote 0
                                          • Alex Warkentin
                                            Alex Warkentin @juggi1962 last edited by

                                            @juggi1962 Poste mal die Logs, wenn der Fehler auftritt

                                            Hier ist das Script, was ich für mich angepasst habe. Achtung! Ich habe die Batterie und andere für mich uninteressante Sachen rausgeschmissen und die Namen von Variablen und Funktionen angepasst. Für die Neuverbindung nach Verbindungsabbruch brauchst du die Zeilen 18 - 27 , 107-122 und 235 -237

                                            // License: Beerware! Do what ever you like with this, but I'm not liable for anything that you do with it.
                                            // If you like this code, feel free to buy me a beer ...
                                            // Have fun with it! der Kachel
                                            // @ts-ignore
                                            var modbusRTU = require("modbus-serial");
                                            var client = new modbusRTU();
                                            
                                            var modbusErrorMessages = [
                                                "Unknown error",
                                                "Illegal function (device does not support this read/write function)",
                                                "Illegal data address (register not supported by device)",
                                                "Illegal data value (value cannot be written to this register)",
                                                "Slave device failure (device reports internal error)",
                                                "Acknowledge (requested data will be available later)",
                                                "Slave device busy (retry request again later)"
                                            ];
                                            
                                            // Enter your inverter modbus IP and port here:
                                            const modbusHost = "000.000.000.000";
                                            const modbusPort = 502;
                                            // Enter the Modbus-IDs of your Sun2000 inverters here:
                                            const modbusID = [1];
                                            // On which Modbus-ID can we reach the power meter? (via Sun2000!)
                                            const powerMeterID = 0;
                                            
                                            // Connect to modbus client
                                            ConnectModbus();
                                            
                                            // These register spaces need to be read:
                                            const registerSpacesToReadContinuously = [[37100, 114], [32000, 116]];
                                            var registerSpacesToReadContinuouslyPtr = 0;
                                            
                                            var globalDataBuffer = new Array(1);
                                            globalDataBuffer[0] = new Array(50000); // not optimized....
                                            
                                            // ---------------------------------------------------------------
                                            // Some helper functions:
                                            function ReadUnsignedInt16(array) {
                                                var value = array[0];    
                                                return value;
                                            }
                                            
                                            function ReadUnsignedInt32(array) {
                                                var value = array[0] * 256 * 256 + array[1];    
                                                return value;
                                            }
                                            
                                            function ReadSignedInt16(array) {
                                                var value = 0;
                                                if (array[0] > 32767)
                                                    value = array[0] - 65535; 
                                                else
                                                    value = array[0];
                                            
                                                return value;
                                            }
                                            function ReadSignedInt32(array) {
                                                var value = 0;
                                                for (var i = 0; i < 2; i++) {
                                                    value = (value << 16) | array[i];
                                                }
                                                return value;
                                            }
                                            function GetU16(dataarray, index) {
                                                var value = ReadUnsignedInt16(dataarray.slice(index, index+1));
                                                return value;
                                            }
                                            
                                            function GetU32(dataarray, index) {
                                                var value = ReadUnsignedInt32(dataarray.slice(index, index+2));
                                                return value;
                                            }
                                            
                                            function GetI16(dataarray, index) {
                                                var value = ReadSignedInt16(dataarray.slice(index, index+1));
                                                return value;
                                            }
                                            
                                            function GetI32(dataarray, index) {
                                                var value = ReadSignedInt32(dataarray.slice(index, index+2));
                                                return value;
                                            }
                                            
                                            function GetString(dataarray, index, length) {
                                                var shortarray = dataarray.slice(index, index+length);
                                                var bytearray = [];
                                                for(var i = 0; i < length; i++) {
                                                    bytearray.push(dataarray[index+i] >> 8);
                                                    bytearray.push(dataarray[index+i] & 0xff);
                                                }       
                                                var value =  String.fromCharCode.apply(null, bytearray);    
                                                return value;
                                            }
                                            
                                            function GetZeroTerminatedString(dataarray, index, length) {
                                                var shortarray = dataarray.slice(index, index+length);
                                                var bytearray = [];
                                                for(var i = 0; i < length; i++) {
                                                    bytearray.push(dataarray[index+i] >> 8);
                                                    bytearray.push(dataarray[index+i] & 0xff);
                                                }       
                                                var value =  String.fromCharCode.apply(null, bytearray);    
                                                var value2 = new String(value).trim();
                                                return value2;
                                            }
                                            
                                            // Funktion zum Herstellen einer Modbus-Verbindung
                                            function ConnectModbus() {
                                                console.log("Init connection to: " + modbusHost +":" + modbusPort);
                                                // set requests parameters
                                                client.setTimeout (10000);
                                                // try to connect
                                                client.connectTCP (modbusHost, { port: modbusPort })
                                                    .then(function()
                                                    {
                                                        console.log("Connected, wait for reading...");
                                                    })
                                                    .catch(function(e)
                                                    {
                                                        console.log(e);
                                                    });
                                            }
                                            
                                            // Funktion zum Anlegen und Beschreiben eines Datenpunkts
                                            function ForceSetState(objectname, value, options) {
                                                if(!existsState("javascript.0." + objectname))      createState(objectname, value, options);
                                                else                                                setState(objectname, value);
                                            }  
                                            // ---------------------------------------------------------------
                                            // Functions to map registers into ioBreaker objects:
                                            function ProcessPowerMeterStatus() {       
                                                ForceSetState("Solarpower.Huawei.Meter.Status",                     GetU16(globalDataBuffer[powerMeterID], 37100),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Meter.VoltageL1",                  GetI32(globalDataBuffer[powerMeterID], 37101) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Meter.VoltageL2",                  GetI32(globalDataBuffer[powerMeterID], 37103) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Meter.VoltageL3",                  GetI32(globalDataBuffer[powerMeterID], 37105) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Meter.CurrentL1",                  GetI32(globalDataBuffer[powerMeterID], 37107) / 100,    {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Meter.CurrentL2",                  GetI32(globalDataBuffer[powerMeterID], 37109) / 100,    {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Meter.CurrentL3",                  GetI32(globalDataBuffer[powerMeterID], 37111) / 100,    {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Meter.ActivePower",                GetI32(globalDataBuffer[powerMeterID], 37113) / 1,      {name: "", unit: "W"});
                                                ForceSetState("Solarpower.Huawei.Meter.ReactivePower",              GetI32(globalDataBuffer[powerMeterID], 37115) / 1,      {name: "", unit: "Var"});
                                                ForceSetState("Solarpower.Huawei.Meter.PowerFactor",                GetI16(globalDataBuffer[powerMeterID], 37117) / 1000,   {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Meter.GridFrequency",              GetI16(globalDataBuffer[powerMeterID], 37118) / 100,    {name: "", unit: "Hz"});
                                                ForceSetState("Solarpower.Huawei.Meter.PositiveActiveEnergy",       GetI32(globalDataBuffer[powerMeterID], 37119) / 100,    {name: "", unit: "kWh"});
                                                ForceSetState("Solarpower.Huawei.Meter.ReverseActiveEnergy",        GetI32(globalDataBuffer[powerMeterID], 37121) / 100,    {name: "", unit: "kWh"});
                                                ForceSetState("Solarpower.Huawei.Meter.AccumulatedReactivePower",   GetI32(globalDataBuffer[powerMeterID], 37123) / 100,    {name: "", unit: "kVarh"});
                                                //ForceSetState("Solarpower.Huawei.Meter.MeterType",                  GetU16(globalDataBuffer[powerMeterID], 37125),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Meter.VoltageL1-L2",               GetI32(globalDataBuffer[powerMeterID], 37126) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Meter.VoltageL2-L3",               GetI32(globalDataBuffer[powerMeterID], 37128) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Meter.VoltageL3-L1",               GetI32(globalDataBuffer[powerMeterID], 37130) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Meter.ActivePowerL1",              GetI32(globalDataBuffer[powerMeterID], 37132) / 1,      {name: "", unit: "W"});
                                                ForceSetState("Solarpower.Huawei.Meter.ActivePowerL2",              GetI32(globalDataBuffer[powerMeterID], 37134) / 1,      {name: "", unit: "W"});
                                                ForceSetState("Solarpower.Huawei.Meter.ActivePowerL3",              GetI32(globalDataBuffer[powerMeterID], 37136) / 1,      {name: "", unit: "W"});
                                                //ForceSetState("Solarpower.Huawei.Meter.MeterModel",                 GetU16(globalDataBuffer[powerMeterID], 37138),          {name: "", unit: ""});
                                            }
                                            
                                            function ProcessInverterStatus(id) {
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".State1",                   GetU16(globalDataBuffer[id-1], 32000),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".State2",                   GetU16(globalDataBuffer[id-1], 32002),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".State3",                   GetU32(globalDataBuffer[id-1], 32003),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Alarm1",                   GetU16(globalDataBuffer[id-1], 32008),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Alarm2",                   GetU16(globalDataBuffer[id-1], 32009),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Alarm3",                   GetU16(globalDataBuffer[id-1], 32010),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".String.1_Voltage",         GetI16(globalDataBuffer[id-1], 32016) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".String.1_Current",         GetI16(globalDataBuffer[id-1], 32017) / 100,    {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".String.2_Voltage",         GetI16(globalDataBuffer[id-1], 32018) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".String.2_Current",         GetI16(globalDataBuffer[id-1], 32019) / 100,    {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".String.3_Voltage",         GetI16(globalDataBuffer[id-1], 32020) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".String.3_Current",         GetI16(globalDataBuffer[id-1], 32021) / 100,    {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".String.4_Voltage",         GetI16(globalDataBuffer[id-1], 32022) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".String.4_Current",         GetI16(globalDataBuffer[id-1], 32023) / 100,    {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".InputPower",               GetI32(globalDataBuffer[id-1], 32064) / 1000,   {name: "", unit: "kW"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L1-L2_Voltage",       GetU16(globalDataBuffer[id-1], 32066) / 10,     {name: "", unit: "V"});      
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L2-L3_Voltage",       GetU16(globalDataBuffer[id-1], 32067) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L3-L1_Voltage",       GetU16(globalDataBuffer[id-1], 32068) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L1_Voltage",          GetU16(globalDataBuffer[id-1], 32069) / 10,     {name: "", unit: "V"});                              
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L2_Voltage",          GetU16(globalDataBuffer[id-1], 32070) / 10,     {name: "", unit: "V"});                                                  
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L3_Voltage",          GetU16(globalDataBuffer[id-1], 32071) / 10,     {name: "", unit: "V"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L1_Current",          GetI32(globalDataBuffer[id-1], 32072) / 1000,   {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L2_Current",          GetI32(globalDataBuffer[id-1], 32074) / 1000,   {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Grid.L3_Current",          GetI32(globalDataBuffer[id-1], 32076) / 1000,   {name: "", unit: "A"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".PeakActivePowerDay",       GetI32(globalDataBuffer[id-1], 32078) / 1000,   {name: "", unit: "kW"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".ActivePower",              GetI32(globalDataBuffer[id-1], 32080) / 1000,   {name: "", unit: "kW"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".ReactivePower",            GetI32(globalDataBuffer[id-1], 32082) / 1000,   {name: "", unit: "kVar"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".PowerFactor",              GetI16(globalDataBuffer[id-1], 32084) / 1000,   {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".GridFrequency",            GetU16(globalDataBuffer[id-1], 32085) / 100,    {name: "", unit: "Hz"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".Efficiency",               GetU16(globalDataBuffer[id-1], 32086) / 100,    {name: "", unit: "%"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".InternalTemperature",      GetI16(globalDataBuffer[id-1], 32087) / 10,     {name: "", unit: "°C"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".InsulationResistance",     GetU16(globalDataBuffer[id-1], 32088) / 1000,   {name: "", unit: "MOhm"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".DeviceStatus",             GetU16(globalDataBuffer[id-1], 32089),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".FaultCode",                GetU16(globalDataBuffer[id-1], 32090),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".StartupTime",              String(new Date(GetU32(globalDataBuffer[id-1], 32091)*1000)),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".ShutdownTime",             String(new Date(GetU32(globalDataBuffer[id-1], 32093)*1000)),          {name: "", unit: ""});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".AccomulatedEnergyYield",   GetU32(globalDataBuffer[id-1], 32106),          {name: "", unit: "kWh"});
                                                ForceSetState("Solarpower.Huawei.Inverter." + id + ".DailyEnergyYield",         GetU32(globalDataBuffer[id-1], 32114),          {name: "", unit: "kWh"});
                                            }
                                            
                                            function ReadRegisterSpace(id, address, length) {
                                                client.setID(modbusID[id-1]);
                                                client.readHoldingRegisters(address, length, function(err, data) {
                                                    if (err) {
                                                        console.warn("Error received reading address " + address + " from id: " + modbusID[id-1] + " with error: " + modbusErrorMessages[err.modbusCode]); 
                                                    }
                                                    else
                                                    {   
                                                        console.debug("Read data from id/address " + modbusID[id-1] + "/" + address + "\nData is: " + data.data);
                                                        for(var i = 0; i < length; i++)  {
                                                            globalDataBuffer[id-1][address+i] = data.data[i];
                                                        } 
                                                    }
                                                });
                                            }
                                            
                                            function ProcessData() {
                                                //console.log("Processing new data...");
                                                for(var i = 1; i <= modbusID.length; i++) {
                                                    //ProcessDeviceInfo(i);
                                                    ProcessInverterStatus(i);
                                                    //processBattery(i);
                                                    //processInverterPowerAdjustments(i);
                                                    //processOptimizers(i); 
                                                }    
                                                ProcessPowerMeterStatus();
                                                //console.log("Processing done!");
                                            }
                                            
                                            
                                            // -------------------------------------------------------------------
                                            // This is the main function triggering a  read via modbus-tcp every two seconds.
                                            // Processing of data is triggered as soon as one complete set of registers is copied.
                                            var triggerprocessing = 0; 
                                            var currentinverter = 1;
                                            
                                            
                                            setInterval(function() {
                                                    if (!client.isOpen){
                                                        ConnectModbus();
                                                    }
                                                    if(triggerprocessing == 1) {
                                                    triggerprocessing = 0;
                                                    ProcessData();        
                                                    }      
                                               
                                                //console.log("Triggering read of inverter " + currentinverter + " at address " + registerSpacesToReadContinuously[registerSpacesToReadContinuouslyPtr][0] + " with length " +  registerSpacesToReadContinuously[registerSpacesToReadContinuouslyPtr][1]);
                                                ReadRegisterSpace(currentinverter, registerSpacesToReadContinuously[registerSpacesToReadContinuouslyPtr][0], registerSpacesToReadContinuously[registerSpacesToReadContinuouslyPtr][1]); 
                                                registerSpacesToReadContinuouslyPtr++;               
                                                if(registerSpacesToReadContinuouslyPtr >= registerSpacesToReadContinuously.length) {
                                                    registerSpacesToReadContinuouslyPtr = 0;
                                                    currentinverter++
                                                    if(currentinverter > modbusID.length){
                                                        currentinverter = 1;  
                                                        triggerprocessing = 1;                    
                                                    }
                                                }     
                                            }, 3000);
                                            
                                            J H 3 Replies Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate
                                            FAQ Cloud / IOT
                                            HowTo: Node.js-Update
                                            HowTo: Backup/Restore
                                            Downloads
                                            BLOG

                                            857
                                            Online

                                            31.8k
                                            Users

                                            79.9k
                                            Topics

                                            1.3m
                                            Posts

                                            60
                                            477
                                            87654
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo