Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

  1. ioBroker Community Home
  2. Deutsch
  3. ioBroker Allgemein
  4. Huawei Sun2000 & ioBroker via JS script funktioniert

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.2k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    1.9k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    15
    1
    2.2k

Huawei Sun2000 & ioBroker via JS script funktioniert

Geplant Angeheftet Gesperrt Verschoben ioBroker Allgemein
481 Beiträge 62 Kommentatoren 121.3k Aufrufe 63 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • Alex WarkentinA Alex Warkentin

    @juggi1962
    Ich nutze eigentlich nur die Infos von Smart Meter. Die active power dort zeigt dir den aktuellen Überschuss oder Bezug. Nagel mich daher nicht darauf fest, aber ich denke Active Power ist das was der WR aktuell in liefert und Input Power müsste das sein, was von den Modulen in den WR geht

    J Offline
    J Offline
    juggi1962
    schrieb am zuletzt editiert von
    #93

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

    @juggi1962
    Ich nutze eigentlich nur die Infos von Smart Meter. Die active power dort zeigt dir den aktuellen Überschuss oder Bezug. Nagel mich daher nicht darauf fest, aber ich denke Active Power ist das was der WR aktuell in liefert und Input Power müsste das sein, was von den Modulen in den WR geht

    Okay, Danke

    baumiliciousnessssB 1 Antwort Letzte Antwort
    0
    • J juggi1962

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

      @juggi1962
      Ich nutze eigentlich nur die Infos von Smart Meter. Die active power dort zeigt dir den aktuellen Überschuss oder Bezug. Nagel mich daher nicht darauf fest, aber ich denke Active Power ist das was der WR aktuell in liefert und Input Power müsste das sein, was von den Modulen in den WR geht

      Okay, Danke

      baumiliciousnessssB Offline
      baumiliciousnessssB Offline
      baumiliciousnessss
      schrieb am zuletzt editiert von
      #94

      Hallo zusammen,
      gerade ist der SUN2000 in Betrieb gegangen mit 10kwh und 11kwp
      Was ist denn der aktuelle Stand hier ? hat es jemand am Laufen?

      J 1 Antwort Letzte Antwort
      0
      • baumiliciousnessssB baumiliciousnessss

        Hallo zusammen,
        gerade ist der SUN2000 in Betrieb gegangen mit 10kwh und 11kwp
        Was ist denn der aktuelle Stand hier ? hat es jemand am Laufen?

        J Offline
        J Offline
        juggi1962
        schrieb am zuletzt editiert von juggi1962
        #95

        @baumiliciousnessss
        Ja, ich habe das Skript von @Alex-Warkentin und das funktioniert jetzt.
        Er hat das Original Skript ein wenig abgespeckt und den Batterie Teil rausgenommen da er und ich keine Haben.

        
        
        // 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 = "xxx.xxx.x.x";
        
        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) / 100,          {name: "", unit: "kWh"});
        
            ForceSetState("Solarpower.Huawei.Inverter." + id + ".DailyEnergyYield",         GetU32(globalDataBuffer[id-1], 32114) / 100,          {name: "", unit: "kWh"});
        
        }
        
         
        
        
        
        function ReadRegisterSpace(id, address, length) {
        
            client.setID(modbusID[id-1]);
        
            client.readHoldingRegisters(address, length, function(err, data) {
        
                if (err) {
        
                    if (err.modbusCode == null) {
        
                        console.warn("Lost connection to client. Trying to reconnect...");
        
                        ConnectModbus();
        
                    } 
        
                    else console.warn("Error received reading address " + address + " from id: " + modbusID[id-1] + " with error: " + 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++) {
        
                ProcessInverterStatus(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 > modbusID.length){
        
                    currentinverter = 1;  
        
                    triggerprocessing = 1;                    
        
                }
        
            }     
        
        }, 4000);
        
        

        Die Fehler die bei mir gekommen sind, sind jetzt fast weg, seit ich die Abfragezeit auf 4000 ms geändert habe.
        Ich hoffe ich konnte helfen, Gruß Jürgen

        AtifanA 1 Antwort Letzte Antwort
        0
        • Alex WarkentinA Alex Warkentin

          @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.

          A Offline
          A Offline
          ATARI
          schrieb am zuletzt editiert von
          #96

          @alex-warkentin
          Mir ging es nicht um den eigentlichen Abfrageintervall, mit dem habe ich schon experimentiert.
          Mein bestes Ergebnis habe ich bei 3333ms erhalten, hierbei treten nur sehr sporadisch Fehlermeldungen
          wegen "...Busy..." auf und ich erhalte dennoch ca. 2 mal pro Minute neue Daten.

          Raspberry Pi 5B (ioB via pi OS_lite(64bit) | Synology NAS (ioB via Docker)

          1 Antwort Letzte Antwort
          0
          • Alex WarkentinA Offline
            Alex WarkentinA Offline
            Alex Warkentin
            schrieb am zuletzt editiert von
            #97

            Funktioniert das Script bei euch noch? Seit heute bekomme ich fast bei jedem Abruf die Fehlermeldung, dass der Port nicht geöffnet ist.

            1 Antwort Letzte Antwort
            0
            • T Thomas42

              Erst mal vielen Dank für das Script, hat fast sofort funtioniert.
              Ich musste nur die IDs raten, bei meiner nagelneuen Anlage mit 2 KTLs und dem Powermeter und ohne Batterien bin ich hier gelandet:

              const ModBusIDs = [1, 2];
              const PowerMeterID = 0; 
              

              Powermeter läuft wunderbar.
              Das Problem, daß die Werte nur einmal geschrieben wurden habe ich mit einem Workaround hier gelöst:

              function forcesetState(objectname, value, options) {
                  if(!existsState(objectname)) {
                      createState(objectname, value, options);   
                      console.log("createstate " +  objectname + " to value " + value);     
                  }
                  //Workaround 
                  setState(objectname, value);
              }  
              
              

              also das setstate aus der else-clause genommen, denn das !existsState scheint nicht sauber zu funktionieren.

              Ach so, noch eine gute Nachricht:
              Der Installateur kann den Modbus (inwischen?) remote aktivieren, da muss keiner vor Ort sein.
              Hat mich eine Mail an meinen Solateur gekostet und zwei Stunden später war alles aktiv.

              severendisS Offline
              severendisS Offline
              severendis
              schrieb am zuletzt editiert von
              #98

              @thomas42

              Hallo Thomas!

              Danke für die Beschreibung, mit der ich das Script zum laufen bekommen habe.
              Aber etwas ist bei Dir scheinbar anders.
              Du schreibts, das du 2 WR hast und die mit der Modbus ID 1 und 2 ansteuerst.
              Hast Du dann an jedem WR einen Dongle dran?

              Bei mir hängen 2 WR im Verbund an einem Dongle.
              Ich habe somit nur eine Modbus Adresse (die 1)

              Bisher arbeite ich über NodeRed (was mir zu langsam und speicherintensiv ist). Da kann ich die Register von beiden WR abfragen.
              Hierfür gibt es eine "Unit-Id"
              So frage ich dort z.B. mit
              32064 Unit-Id 1 die PV Input Power des ersten WR ab
              32064 Unit-Id 2 die PV Input Power des zweiten WR ab

              Das kann ich aber in diesem Script nicht finden und somit nur einen WR auslesen.

              Wie sind die WR bei Dir angeschlossen?

              1 Antwort Letzte Antwort
              0
              • O Offline
                O Offline
                OliWit82
                schrieb am zuletzt editiert von
                #99

                Hallo zusammen.

                Vielen Dank das Script läuft super.

                Hat vielleicht jemand die Adresse für die Last vom Haus?

                Danke

                1 Antwort Letzte Antwort
                0
                • O Offline
                  O Offline
                  OliWit82
                  schrieb am zuletzt editiert von
                  #100

                  Kann man die Werte abfragen?
                  Oder muss man dich durch ein Script selber errechnen?

                  IMG_3604.jpeg

                  B 1 Antwort Letzte Antwort
                  0
                  • O OliWit82

                    Kann man die Werte abfragen?
                    Oder muss man dich durch ein Script selber errechnen?

                    IMG_3604.jpeg

                    B Offline
                    B Offline
                    badsnoopy667
                    schrieb am zuletzt editiert von badsnoopy667
                    #101

                    @oliwit82
                    Die Werte kann man nicht direkt abfragen und müssen berechnet werden.

                    Beispiel

                    Oh, sehe gerade, mein Script ist gar nicht für die kWh Werte. Damit berechne ich erstmal Verbrauch, Bezug, etc. Aber diese Werte kann man dann ja aufsummieren über den Tag.

                    O 1 Antwort Letzte Antwort
                    0
                    • B badsnoopy667

                      @oliwit82
                      Die Werte kann man nicht direkt abfragen und müssen berechnet werden.

                      Beispiel

                      Oh, sehe gerade, mein Script ist gar nicht für die kWh Werte. Damit berechne ich erstmal Verbrauch, Bezug, etc. Aber diese Werte kann man dann ja aufsummieren über den Tag.

                      O Offline
                      O Offline
                      OliWit82
                      schrieb am zuletzt editiert von
                      #102

                      @badsnoopy667

                      Danke.

                      Gibt es da vielleicht schon ein fertiges blockly?

                      B 1 Antwort Letzte Antwort
                      0
                      • O OliWit82

                        @badsnoopy667

                        Danke.

                        Gibt es da vielleicht schon ein fertiges blockly?

                        B Offline
                        B Offline
                        badsnoopy667
                        schrieb am zuletzt editiert von
                        #103

                        @oliwit82
                        Das sollte sich mit dem sourceanalytix Adapter am einfachsten realisieren lassen.

                        1 Antwort Letzte Antwort
                        0
                        • J juggi1962

                          @baumiliciousnessss
                          Ja, ich habe das Skript von @Alex-Warkentin und das funktioniert jetzt.
                          Er hat das Original Skript ein wenig abgespeckt und den Batterie Teil rausgenommen da er und ich keine Haben.

                          
                          
                          // 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 = "xxx.xxx.x.x";
                          
                          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) / 100,          {name: "", unit: "kWh"});
                          
                              ForceSetState("Solarpower.Huawei.Inverter." + id + ".DailyEnergyYield",         GetU32(globalDataBuffer[id-1], 32114) / 100,          {name: "", unit: "kWh"});
                          
                          }
                          
                           
                          
                          
                          
                          function ReadRegisterSpace(id, address, length) {
                          
                              client.setID(modbusID[id-1]);
                          
                              client.readHoldingRegisters(address, length, function(err, data) {
                          
                                  if (err) {
                          
                                      if (err.modbusCode == null) {
                          
                                          console.warn("Lost connection to client. Trying to reconnect...");
                          
                                          ConnectModbus();
                          
                                      } 
                          
                                      else console.warn("Error received reading address " + address + " from id: " + modbusID[id-1] + " with error: " + 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++) {
                          
                                  ProcessInverterStatus(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 > modbusID.length){
                          
                                      currentinverter = 1;  
                          
                                      triggerprocessing = 1;                    
                          
                                  }
                          
                              }     
                          
                          }, 4000);
                          
                          

                          Die Fehler die bei mir gekommen sind, sind jetzt fast weg, seit ich die Abfragezeit auf 4000 ms geändert habe.
                          Ich hoffe ich konnte helfen, Gruß Jürgen

                          AtifanA Offline
                          AtifanA Offline
                          Atifan
                          schrieb am zuletzt editiert von
                          #104

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

                          @baumiliciousnessss
                          Ja, ich habe das Skript von @Alex-Warkentin und das funktioniert jetzt.
                          Er hat das Original Skript ein wenig abgespeckt und den Batterie Teil rausgenommen da er und ich keine Haben.

                          
                          
                          // 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 = "xxx.xxx.x.x";
                          
                          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) / 100,          {name: "", unit: "kWh"});
                          
                              ForceSetState("Solarpower.Huawei.Inverter." + id + ".DailyEnergyYield",         GetU32(globalDataBuffer[id-1], 32114) / 100,          {name: "", unit: "kWh"});
                          
                          }
                          
                           
                          
                          
                          
                          function ReadRegisterSpace(id, address, length) {
                          
                              client.setID(modbusID[id-1]);
                          
                              client.readHoldingRegisters(address, length, function(err, data) {
                          
                                  if (err) {
                          
                                      if (err.modbusCode == null) {
                          
                                          console.warn("Lost connection to client. Trying to reconnect...");
                          
                                          ConnectModbus();
                          
                                      } 
                          
                                      else console.warn("Error received reading address " + address + " from id: " + modbusID[id-1] + " with error: " + 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++) {
                          
                                  ProcessInverterStatus(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 > modbusID.length){
                          
                                      currentinverter = 1;  
                          
                                      triggerprocessing = 1;                    
                          
                                  }
                          
                              }     
                          
                          }, 4000);
                          
                          

                          Die Fehler die bei mir gekommen sind, sind jetzt fast weg, seit ich die Abfragezeit auf 4000 ms geändert habe.
                          Ich hoffe ich konnte helfen, Gruß Jürgen

                          Hallo, habe auch diese Skript genommen und funktioniert bei mir auch.
                          Nur habe ich noch eine LUNA2000 Batterie mit 10kWh und würde die gerne mit einbinden.
                          Kann mir einer sagen was ich noch mit einfügen muss, damit der Speicher mit drin ist?
                          Danke!

                          1 Antwort Letzte Antwort
                          0
                          • Alex WarkentinA Offline
                            Alex WarkentinA Offline
                            Alex Warkentin
                            schrieb am zuletzt editiert von
                            #105

                            Du solltest dann das Ursprungs-Script von Kachel aus dem ersten Post nehmen und beide ggf. kombinieren.

                            X 1 Antwort Letzte Antwort
                            0
                            • G Offline
                              G Offline
                              g.polat
                              schrieb am zuletzt editiert von g.polat
                              #106

                              Hallo zusammen,
                              habe nun das Script ebenfalls zum laufen bekommen, habe jedoch einige Verständnisfragen.
                              Was ist der Unterschied zwischen:
                              javascript.0.Solarpower.Huawei.Meter.ActivePower und javascript.0.Solarpower.Huawei.Meter.ActivePower
                              Welche Datenpunkte muss ich für den Energiefluss nehmen betreffend: Hausverbrauch; Netzeinspeisung; Netzausspeisung?
                              Wäre für Hilfestellung dankbar, da die Werte aus der APP nicht mit den ausgelesenen Werten bis auf den Akku übereinstimmen.

                              Laut AP aktuell:
                              Produktion 4,79 KW
                              Batterie wird mit 2,47 KW geladen
                              Ins Netz gehen 1,96 KW
                              Ins Haus 0,35KW

                              Ausgelesen per Script:
                              javascript.0.Solarpower.Huawei.Inverter.1.ActivePower 1.249 KW
                              javascript.0.Solarpower.Huawei.Inverter.1.InputPower 4.42 KW
                              javascript.0.Solarpower.Huawei.Meter.ActivePower 260 W
                              javascript.0.Solarpower.Huawei.Meter.PositiveActiveEnergy 1.49 KW

                              Hier mein Scrpt:

                              // 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.0.45", { port: 502 });
                              // 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;
                              // 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",   getU32(GlobalDataBuffer[id-1], 32106) / 100, {name: "", unit: "kWh"});
                                  forcesetState("Solarpower2.Huawei.Inverter." + id + ".DailyEnergyYield",         getU32(GlobalDataBuffer[id-1], 32114) / 100, {name: "", unit: "kWh"});
                                  
                                  //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;                    
                                      }
                                  }     
                              }, 4000);
                              
                              

                              Gruß
                              GP

                              1 Antwort Letzte Antwort
                              0
                              • Alex WarkentinA Alex Warkentin

                                Du solltest dann das Ursprungs-Script von Kachel aus dem ersten Post nehmen und beide ggf. kombinieren.

                                X Offline
                                X Offline
                                Xanon
                                schrieb am zuletzt editiert von Xanon
                                #107

                                @alex-warkentin
                                Hallo, auch bei mir ist jetzt ein Speicher dazugekommen.
                                Ich habe wie du empfohlen hast auch das AnfangsScript genommen, allerdings fehlen mir die Kenntnisse alle Optimierungen wie z.B. (den täglichen Ertrag (DailyEnergyYield)) oder (die Zeit für Wechselrichter Shutdown / Start als Uhrzeit / Datum) nachträglich mit einzubauen und ich bekomme immer wieder Fehlermeldungen ins Log und weiss nicht wie ich Sie behandeln kann.

                                2023-05-20 11:34:33.284	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 38300 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:33:29.251	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 37800 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:32:27.244	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 37700 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:31:23.234	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 32000 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:31:13.244	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 38300 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:30:19.236	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 30000 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:30:03.237	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 32000 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:29:15.196	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 38400 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:28:13.192	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 38300 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:27:09.180	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 37800 from id: 1 with error: undefined
                                
                                javascript.0
                                2023-05-20 11:26:05.178	warn	script.js.Solar.PV_mit_Speicher_Berechnung: Error received reading address 37000 from id: 1 with error: undefined
                                

                                Wärst du oder vielleicht jemand anderes so freundlich und würde mir sein Skript welches den Batterie Speicher beinhaltet und optimiert / verbessert ist zur Verfügung stellen?

                                Vielen Dank

                                1 Antwort Letzte Antwort
                                0
                                • C Offline
                                  C Offline
                                  Chris_B
                                  schrieb am zuletzt editiert von
                                  #108

                                  @Kachel
                                  Ich habe Deine Skript auch bei mir implementiert (5KWp, 15 kWh Speicher).
                                  Es läuft, ich hatte aber folgendes Problem bei meiner iobroker Installation: Die Funktion forcesetState() funktioniert bei mir nicht. Dadurch werden das erste Mal die Werte gelesen, danach aber nicht mehr, da nur createState() aufgerufen wird. Ich musste das folgendermassen abändern:

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

                                  D.h. ich muss beim Prüfen des State javascript.0 voranstellen.
                                  Danach läuft das Skript gut.
                                  Ich habe eine weitere Optimierung vorgenommen: Jetzt wird bei jedem Setzen der States geprüft ob der State existiert. Das ist ziemlich aufwendig. Ich mache das nun nur ein Mal pro 'Runde', und merke mir das in einer Variable. Dadurch wird nicht dauernd geprüft; spart etwas Processing Power...

                                  X 1 Antwort Letzte Antwort
                                  0
                                  • C Chris_B

                                    @Kachel
                                    Ich habe Deine Skript auch bei mir implementiert (5KWp, 15 kWh Speicher).
                                    Es läuft, ich hatte aber folgendes Problem bei meiner iobroker Installation: Die Funktion forcesetState() funktioniert bei mir nicht. Dadurch werden das erste Mal die Werte gelesen, danach aber nicht mehr, da nur createState() aufgerufen wird. Ich musste das folgendermassen abändern:

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

                                    D.h. ich muss beim Prüfen des State javascript.0 voranstellen.
                                    Danach läuft das Skript gut.
                                    Ich habe eine weitere Optimierung vorgenommen: Jetzt wird bei jedem Setzen der States geprüft ob der State existiert. Das ist ziemlich aufwendig. Ich mache das nun nur ein Mal pro 'Runde', und merke mir das in einer Variable. Dadurch wird nicht dauernd geprüft; spart etwas Processing Power...

                                    X Offline
                                    X Offline
                                    Xanon
                                    schrieb am zuletzt editiert von
                                    #109

                                    @chris_b
                                    Würdest du dein Skript hier zur Verfügung stellen?

                                    G C 2 Antworten Letzte Antwort
                                    0
                                    • X Xanon

                                      @chris_b
                                      Würdest du dein Skript hier zur Verfügung stellen?

                                      G Offline
                                      G Offline
                                      g.polat
                                      schrieb am zuletzt editiert von
                                      #110

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

                                      @chris_b
                                      Würdest du dein Skript hier zur Verfügung stellen?

                                      Funktioniert bei mir mir 10kw Akku perfekt.

                                      // 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.0.45", { port: 502 });
                                      // 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;
                                      // 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",     getU16(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",   getU32(GlobalDataBuffer[id-1], 32106) / 100, {name: "", unit: "kWh"});
                                          forcesetState("Solarpower2.Huawei.Inverter." + id + ".DailyEnergyYield",         getU32(GlobalDataBuffer[id-1], 32114) / 100, {name: "", unit: "kWh"});
                                          
                                          //forcesetState("Solarpower.Huawei.Inverter." + id + ".AccomulatedEnergyYield",    getU32(GlobalDataBuffer[id-1], 32106) / 100, {name: "", unit: "kWh"});
                                          //forcesetState("Solarpower.Huawei.Inverter." + id + ".DailyEnergyYield",          getU32(GlobalDataBuffer[id-1], 32114) / 100, {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;                    
                                              }
                                          }     
                                      }, 4000);
                                      
                                      
                                      X 1 Antwort Letzte Antwort
                                      0
                                      • X Xanon

                                        @chris_b
                                        Würdest du dein Skript hier zur Verfügung stellen?

                                        C Offline
                                        C Offline
                                        Chris_B
                                        schrieb am zuletzt editiert von
                                        #111

                                        @xanon Mach' ich in den nächsten 1-2 Tagen. Ich möchte noch ein paar weitere Verbesserungen vornehmen, dann stelle ich das Skript zur Verfügung.

                                        X 1 Antwort Letzte Antwort
                                        0
                                        • G g.polat

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

                                          @chris_b
                                          Würdest du dein Skript hier zur Verfügung stellen?

                                          Funktioniert bei mir mir 10kw Akku perfekt.

                                          // 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.0.45", { port: 502 });
                                          // 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;
                                          // 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",     getU16(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",   getU32(GlobalDataBuffer[id-1], 32106) / 100, {name: "", unit: "kWh"});
                                              forcesetState("Solarpower2.Huawei.Inverter." + id + ".DailyEnergyYield",         getU32(GlobalDataBuffer[id-1], 32114) / 100, {name: "", unit: "kWh"});
                                              
                                              //forcesetState("Solarpower.Huawei.Inverter." + id + ".AccomulatedEnergyYield",    getU32(GlobalDataBuffer[id-1], 32106) / 100, {name: "", unit: "kWh"});
                                              //forcesetState("Solarpower.Huawei.Inverter." + id + ".DailyEnergyYield",          getU32(GlobalDataBuffer[id-1], 32114) / 100, {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;                    
                                                  }
                                              }     
                                          }, 4000);
                                          
                                          
                                          X Offline
                                          X Offline
                                          Xanon
                                          schrieb am zuletzt editiert von
                                          #112

                                          @g-polat Super Vielen Dank
                                          Werde ich mal testen 👍

                                          1 Antwort Letzte Antwort
                                          0
                                          Antworten
                                          • In einem neuen Thema antworten
                                          Anmelden zum Antworten
                                          • Älteste zuerst
                                          • Neuste zuerst
                                          • Meiste Stimmen


                                          Support us

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

                                          250

                                          Online

                                          32.4k

                                          Benutzer

                                          81.4k

                                          Themen

                                          1.3m

                                          Beiträge
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Anmelden

                                          • Du hast noch kein Konto? Registrieren

                                          • Anmelden oder registrieren, um zu suchen
                                          • Erster Beitrag
                                            Letzter Beitrag
                                          0
                                          • Home
                                          • Aktuell
                                          • Tags
                                          • Ungelesen 0
                                          • Kategorien
                                          • Unreplied
                                          • Beliebt
                                          • GitHub
                                          • Docu
                                          • Hilfe