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.2k 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.
  • B badsnoopy667

    @majawe
    Schön, dass es klappt! Aber ENT-laden im Ladezeitraum tut er nicht, oder? Das ist nämlich vermutlich noch der Haken. Den Zeitraum würde ich ja immer (in der Nacht) stehen lassen und über die Ladeleistung dann quasi aktivieren und deaktivieren.
    Wobei man streiten kann, ob das ein Problem ist, im Winter ist der Akku Nachts sowieso fast immer leer. Dann spielt es keine Rolle. Und im Sommer brauche ich ihn ihn nicht extern laden.

    Zu der FusionSolar Seite: Wo geht das denn? Bei mir kann ich da gar nix einstellen. Welche Dongle Firmware ist das? Oder hast Du da Installateur Zugriff auf FusionSolar?

    M Offline
    M Offline
    majawe
    schrieb am zuletzt editiert von
    #38

    @badsnoopy667 Ich denke bei sonnenuntergang setze ich den auf 0watt, und dann wenn kleiner als 5cent = 5000Watt. Den Rest erledigt Tou zwischen 0 - 5 Uhr.

    1 Antwort Letzte Antwort
    0
    • B badsnoopy667

      @majawe
      Schön, dass es klappt! Aber ENT-laden im Ladezeitraum tut er nicht, oder? Das ist nämlich vermutlich noch der Haken. Den Zeitraum würde ich ja immer (in der Nacht) stehen lassen und über die Ladeleistung dann quasi aktivieren und deaktivieren.
      Wobei man streiten kann, ob das ein Problem ist, im Winter ist der Akku Nachts sowieso fast immer leer. Dann spielt es keine Rolle. Und im Sommer brauche ich ihn ihn nicht extern laden.

      Zu der FusionSolar Seite: Wo geht das denn? Bei mir kann ich da gar nix einstellen. Welche Dongle Firmware ist das? Oder hast Du da Installateur Zugriff auf FusionSolar?

      M Offline
      M Offline
      majawe
      schrieb am zuletzt editiert von majawe
      #39

      @badsnoopy667 Ich habe den Installateur zugang, da ist der Punkt sichtbar. Der Dongle hat die FW PC133 am ende aber gesehen habe ich den Punkt bereits mit der PC130

      1 Antwort Letzte Antwort
      0
      • T Offline
        T Offline
        Thomas42
        schrieb am zuletzt editiert von Thomas42
        #40

        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 1 Antwort Letzte Antwort
        0
        • ? Ein ehemaliger Benutzer

          @majawe

          Vielen Dank, wusste garnicht das man das machen kann ... Wieder etwas gelernt ...

          Das Script startet jetzt, aber ich bekomme leider keine Daten ausgelesen.

          Habe die Werte bei mir jetzt so angepasst (ich habe leider - noch - keinen Akku):

          client.connectTCP("10.168.1.111", { port: 502 });
          const ModBusIDs = [1];
          const PowerMeterID = 0;
          const BatteryUnits = [[0, 0]];

          Folgende Infos find ich im Log:

          30.12.2022, 11:33:51.829 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 35300 with length 40
          30.12.2022, 11:33:51.830 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 35300 from id: 1 with error: undefined
          30.12.2022, 11:33:53.829 [info ]: javascript.0 (1120689) script.js.PV: Processing new data...
          30.12.2022, 11:33:53.832 [info ]: javascript.0 (1120689) script.js.PV: Processing done!
          30.12.2022, 11:33:53.833 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 30000 with length 81
          30.12.2022, 11:33:53.833 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 30000 from id: 1 with error: undefined
          30.12.2022, 11:33:55.830 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 37100 with length 114
          30.12.2022, 11:33:55.830 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 37100 from id: 1 with error: undefined
          30.12.2022, 11:33:57.830 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 32000 with length 116
          30.12.2022, 11:33:57.830 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 32000 from id: 1 with error: undefined
          30.12.2022, 11:33:59.830 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 37000 with length 68
          30.12.2022, 11:33:59.831 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 37000 from id: 1 with error: undefined
          30.12.2022, 11:34:01.830 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 37700 with length 100
          30.12.2022, 11:34:01.831 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 37700 from id: 1 with error: undefined
          30.12.2022, 11:34:03.831 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 37800 with length 100
          30.12.2022, 11:34:03.831 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 37800 from id: 1 with error: undefined
          30.12.2022, 11:34:05.831 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 38200 with length 100
          30.12.2022, 11:34:05.832 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 38200 from id: 1 with error: undefined
          30.12.2022, 11:34:07.832 [info ]: javascript.0 (1120689) script.js.PV: Triggering read of inverter 1 at address 38300 with length 100
          30.12.2022, 11:34:07.833 [warn ]: javascript.0 (1120689) script.js.PV: Error received reading address 38300 from id: 1 with error: undefined
          30.12.2022, 11:34:08.028 [info ]: javascript.0 (1120689) Stop script script.js.PV

          oswibzO Offline
          oswibzO Offline
          oswibz
          schrieb am zuletzt editiert von oswibz
          #41

          @zoid1988 Hallo zusammen, gibt es hier Neuigkeiten. Hab heute mein WR angeschlossen. Datenpunkte wurden generiert aber erhalte den selben Fehler. Gibt es Lösungen? Danke an alle für die Hilfe!

          Ich habe auch den Workaround eingesetzt, erhalte immer aber die gleiche Warnung:
          21:02:25.393 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 30000 with length 81
          21:02:25.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 30000 from id: 1 with error: undefined
          21:02:27.393 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37100 with length 114
          21:02:27.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37100 from id: 1 with error: undefined
          21:02:29.394 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 32000 with length 116
          21:02:29.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 32000 from id: 1 with error: undefined
          21:02:31.394 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37000 with length 68
          21:02:31.395 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37000 from id: 1 with error: undefined
          21:02:33.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37700 with length 100
          21:02:33.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37700 from id: 1 with error: undefined
          21:02:35.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37800 with length 100
          21:02:35.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37800 from id: 1 with error: undefined
          21:02:37.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38200 with length 100
          21:02:37.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38200 from id: 1 with error: undefined
          21:02:39.406 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38300 with length 100
          21:02:39.406 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38300 from id: 1 with error: undefined
          21:02:41.406 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38400 with length 100
          21:02:41.407 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38400 from id: 1 with error: undefined
          21:02:43.407 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 35300 with length 40
          21:02:43.408 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 35300 from id: 1 with error: undefined

          oswibzO ? 2 Antworten Letzte Antwort
          0
          • oswibzO oswibz

            @zoid1988 Hallo zusammen, gibt es hier Neuigkeiten. Hab heute mein WR angeschlossen. Datenpunkte wurden generiert aber erhalte den selben Fehler. Gibt es Lösungen? Danke an alle für die Hilfe!

            Ich habe auch den Workaround eingesetzt, erhalte immer aber die gleiche Warnung:
            21:02:25.393 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 30000 with length 81
            21:02:25.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 30000 from id: 1 with error: undefined
            21:02:27.393 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37100 with length 114
            21:02:27.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37100 from id: 1 with error: undefined
            21:02:29.394 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 32000 with length 116
            21:02:29.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 32000 from id: 1 with error: undefined
            21:02:31.394 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37000 with length 68
            21:02:31.395 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37000 from id: 1 with error: undefined
            21:02:33.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37700 with length 100
            21:02:33.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37700 from id: 1 with error: undefined
            21:02:35.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37800 with length 100
            21:02:35.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37800 from id: 1 with error: undefined
            21:02:37.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38200 with length 100
            21:02:37.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38200 from id: 1 with error: undefined
            21:02:39.406 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38300 with length 100
            21:02:39.406 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38300 from id: 1 with error: undefined
            21:02:41.406 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38400 with length 100
            21:02:41.407 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38400 from id: 1 with error: undefined
            21:02:43.407 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 35300 with length 40
            21:02:43.408 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 35300 from id: 1 with error: undefined

            oswibzO Offline
            oswibzO Offline
            oswibz
            schrieb am zuletzt editiert von
            #42

            Dear all, any support on my issue (see above).

            Thanks for your support

            T 1 Antwort Letzte Antwort
            0
            • oswibzO oswibz

              Dear all, any support on my issue (see above).

              Thanks for your support

              T Offline
              T Offline
              Thomas42
              schrieb am zuletzt editiert von
              #43

              @oswibz
              Als Newbie: Da stimmen Deine IDs nicht. So, wie ich das Script verstehe, gibt es die ID, aber es ist nicht der Gerätetyp, der abgefragt wird.

              oswibzO 1 Antwort Letzte Antwort
              0
              • T Thomas42

                @oswibz
                Als Newbie: Da stimmen Deine IDs nicht. So, wie ich das Script verstehe, gibt es die ID, aber es ist nicht der Gerätetyp, der abgefragt wird.

                oswibzO Offline
                oswibzO Offline
                oswibz
                schrieb am zuletzt editiert von
                #44

                @thomas42
                wo finde ich den korrekten ID?

                T 1 Antwort Letzte Antwort
                0
                • oswibzO oswibz

                  @thomas42
                  wo finde ich den korrekten ID?

                  T Offline
                  T Offline
                  Thomas42
                  schrieb am zuletzt editiert von
                  #45

                  @oswibz Keine Ahnung, ich habe geraten.
                  Das Smartmeter scheint immer die Null zu sein, der erste WR war bei die 1, der zweite die 2.

                  1 Antwort Letzte Antwort
                  0
                  • W Offline
                    W Offline
                    WILHER
                    schrieb am zuletzt editiert von
                    #46

                    Hallo zusammen, versuche auch meinen SUN2000 ausgelesen zu bekommen, leider funktioniert es nicht. Es werde auch irgendwie keine Werte geschrieben. Habe 1 String, 1 Batteriespeicher LUNA2000 10kw. Was fehlt hier ggf noch?

                    // 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.10.101", { port: 502 });
                    // Enter the Modbus-IDs of your Sun2000 inverters here:
                    const ModBusIDs = [16, 1];
                    // On which Modbus-ID can we reach the power meter? (via Sun2000!)
                    const PowerMeterID = 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, 2], [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(objectname)) {
                    createState(objectname, value, options);
                    }
                    else {
                    setState(objectname, value);
                    }
                    }
                    // ---------------------------------------------------------------
                    // Functions to map registers into ioBreaker objects:
                    function processOptimizers(id) {
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerTotalNumber", getU16(GlobalDataBuffer[id-1], 35200), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerOnlineNumber", getU16(GlobalDataBuffer[id-1], 35201), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerFeatureData", getU16(GlobalDataBuffer[id-1], 35202), {name: "", unit: ""});
                    }

                    function processInverterPowerAdjustments(id) {
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementMode", getU16(GlobalDataBuffer[id-1], 35300), {name: "", unit: ""});
                    forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementCommand", getU16(GlobalDataBuffer[id-1], 35303), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementMode", getU16(GlobalDataBuffer[id-1], 35304), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementValue", getU32(GlobalDataBuffer[id-1], 35305), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementCommand",getU16(GlobalDataBuffer[id-1], 35307), {name: "", unit: ""});
                    forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RunningStatus", getU16(GlobalDataBuffer[id-1], 37000), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.ChargeAndDischargePower",getI32(GlobalDataBuffer[id-1], 37001), {name: "Charge and Discharge Power", unit: "W"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BusVoltage", getU16(GlobalDataBuffer[id-1], 37003) / 10, {name: "Busvoltage", unit: "V"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BatterySOC", getU16(GlobalDataBuffer[id-1], 37004) / 10, {name: "Battery SOC", unit: "%"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.WorkingMode", getU16(GlobalDataBuffer[id-1], 37006), {name: "Working Mode", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RatedChargePower", getU32(GlobalDataBuffer[id-1], 37007), {name: "", unit: "W"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RatedDischargePower", getU32(GlobalDataBuffer[id-1], 37009), {name: "", unit: "W"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.FaultID", getU16(GlobalDataBuffer[id-1], 37014), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayChargeCapacity", getU32(GlobalDataBuffer[id-1], 37015) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37017) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BusCurrent", getI16(GlobalDataBuffer[id-1], 37021) / 10, {name: "Buscurrent", unit: "A"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BatteryTemperature", getI16(GlobalDataBuffer[id-1], 37022) / 10, {name: "Battery Temperatue", unit: "°C"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RemainingChargeDischargeTime", getU16(GlobalDataBuffer[id-1], 37025), {name: "", unit: "mins"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.DCDCversion", getZeroTerminatedString(GlobalDataBuffer[id-1], 37026, 10), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BMSversion", getZeroTerminatedString(GlobalDataBuffer[id-1], 37036, 10), {name: "", unit: ""});
                    }
                    // Battery registers 16+17 (Storage-related)
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.MaximumChargePower", getU32(GlobalDataBuffer[id-1], 37046), {name: "", unit: "W"});
                    forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.SN",                         getZeroTerminatedString(GlobalDataBuffer[id-1], 37052, 10), {name: "Serialnumber", unit: ""});       
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.TotalCharge",                getU32(GlobalDataBuffer[id-1], 37066) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.SN",                     getZeroTerminatedString(GlobalDataBuffer[id-1], 37700, 10), {name: "Serialnumber", unit: ""});        
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BatterySOC",             getU16(GlobalDataBuffer[id-1], 37738) / 10, {name: "", unit: "%"});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.RunningStatus",          getU16(GlobalDataBuffer[id-1], 37741), {name: "", unit: ""});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.ChargeAndDischargePower",getI32(GlobalDataBuffer[id-1], 37743), {name: "", unit: "W"});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayChargeCapacity",    getU32(GlobalDataBuffer[id-1], 37746) / 100, {name: "", unit: "kWh"});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37748) / 100, {name: "", unit: "kWh"});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BusVoltage",             getU16(GlobalDataBuffer[id-1], 37750) / 10, {name: "", unit: "V"});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BusCurrent",             getI16(GlobalDataBuffer[id-1], 37751) / 10, {name: "", unit: "A"});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BatteryTemperature",     getI16(GlobalDataBuffer[id-1], 37752) / 10, {name: "", unit: "°C"});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.TotalCharge",                 getU32(GlobalDataBuffer[id-1], 37753) / 100, {name: "", unit: "kWh"});
                        forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.TotalDischarge",              getU32(GlobalDataBuffer[id-1], 37755) / 100, {name: "", unit: "kWh"});
                    }
                    // Battery register 32-41 (Storage related)
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.RatedCapacity", getU32(GlobalDataBuffer[id-1], 37758) / 1, {name: "", unit: "Wh"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.SOC", getU16(GlobalDataBuffer[id-1], 37760) / 10, {name: "", unit: "%"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.RunningStatus", getU16(GlobalDataBuffer[id-1], 37762) / 1, {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.BusVoltage", getU16(GlobalDataBuffer[id-1], 37763) / 10, {name: "", unit: "V"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.BusCurrent", getI16(GlobalDataBuffer[id-1], 37764) / 10, {name: "", unit: "A"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 37765) / 1, {name: "", unit: "W"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.TotalCharge", getU32(GlobalDataBuffer[id-1], 37780) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.TotalDischarge", getU32(GlobalDataBuffer[id-1], 37782) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.CurrentDayChargeCapacity", getU32(GlobalDataBuffer[id-1], 37784) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.SoftwareVersion",    getZeroTerminatedString(GlobalDataBuffer[id-1], 37814, 8), {name: "Softwareversion", unit: ""});
                    }
                    if(BatteryUnits[id-1][0] > 0) {
                        forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".SN",                getZeroTerminatedString(GlobalDataBuffer[id-1], 38200+(i-1)*126+(j-1)*42, 6), {name: "", unit: ""});
                                forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".FirmwareVersion",   getZeroTerminatedString(GlobalDataBuffer[id-1], 38210+(i-1)*126+(j-1)*42, 8), {name: "", unit: ""});
                                forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".WorkingStatus",     getU16(GlobalDataBuffer[id-1], 38228+(i-1)*126+(j-1)*42), {name: "", unit: ""});
                                forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".BatterySOC",        getU16(GlobalDataBuffer[id-1], 38229+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "%"});
                                forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 38233+(i-1)*126+(j-1)*42) / 1000, {name: "", unit: "kW"});
                                forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Voltage",           getU16(GlobalDataBuffer[id-1], 38235+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "V"});
                                forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Current",           getI16(GlobalDataBuffer[id-1], 38236+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "A"});
                                forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".TotalCharge",       getU32(GlobalDataBuffer[id-1], 38238+(i-1)*126+(j-1)*42) / 100, {name: "", unit: "kWh"});
                                forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".MaxTemperature", getI16(GlobalDataBuffer[id-1], 38452+(i-1)*6+(j-1)*2) / 10, {name: "", unit: "°C"});
                                createState("Solarpower.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("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], 32001), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".State3", getU16(GlobalDataBuffer[id-1], 32002), {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 + ".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", getU16(GlobalDataBuffer[id-1], 32091), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".ShutdownTime", getU16(GlobalDataBuffer[id-1], 32093), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".AccomulatedEnergyYield", getU16(GlobalDataBuffer[id-1], 32106), {name: "", unit: "kWh"});
                    forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Model", getZeroTerminatedString(GlobalDataBuffer[id-1], 30000, 8), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".SN", getZeroTerminatedString(GlobalDataBuffer[id-1], 30015, 6), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".PN", getZeroTerminatedString(GlobalDataBuffer[id-1], 30025, 6), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".ModelID", getU16(GlobalDataBuffer[id-1], 30070), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".PVStrings", getU16(GlobalDataBuffer[id-1], 30071), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".MPPTrackers", getU16(GlobalDataBuffer[id-1], 30072), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxRatedPower", getU32(GlobalDataBuffer[id-1], 30073) / 1000, {name: "", unit: "kW"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxActivePower", getU32(GlobalDataBuffer[id-1], 30075) / 1000, {name: "", unit: "kW"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxApparentPower", getU32(GlobalDataBuffer[id-1], 30077) / 1000, {name: "", unit: "kVA"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxReactivePowerToGrid", getI32(GlobalDataBuffer[id-1], 30079) / 1000, {name: "", unit: "kVAr"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxReactivePowerFromGrid", getI32(GlobalDataBuffer[id-1], 30081) / 1000, {name: "", unit: "kVAr"});
                    }

                    function readRegisterSpace(id, address, length) {
                    client.setID(ModBusIDs[id-1]);
                    client.readHoldingRegisters(address, length, function(err, data) {
                    if (err) {
                    console.warn("Error received reading address " + address + " from id: " + ModBusIDs[id-1] + " with error: " + modbusErrorMessages[err.modbusCode]);
                    }
                    else
                    {
                    console.debug("Read data from id/address " + ModBusIDs[id-1] + "/" + address + "\nData is: " + data.data);
                    for(var i = 0; i < length; i++) {
                    GlobalDataBuffer[id-1][address+i] = data.data[i];
                    }
                    }
                    });
                    }

                    function processData() {
                    console.log("Processing new data...");
                    for(var i = 1; i <= ModBusIDs.length; i++) {
                    ProcessDeviceInfo(i);
                    processInverterStatus(i);
                    processBattery(i);
                    processInverterPowerAdjustments(i);
                    processOptimizers(i);
                    }
                    ProcessPowerMeterStatus();
                    console.log("Processing done!");
                    }

                    // -------------------------------------------------------------------
                    // This is the main function triggering a read via modbus-tcp every two seconds.
                    // Processing of data is triggered as soon as one complete set of registers is copied.
                    var triggerprocessing = 0;
                    var currentinverter = 1;

                    setInterval(function() {
                    if(triggerprocessing == 1) {
                    triggerprocessing = 0;
                    processData();
                    }

                    console.log("Triggering read of inverter " + currentinverter + " at address " + RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0] + " with length " +  RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]);
                    readRegisterSpace(currentinverter, RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0], RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]); 
                    RegisterSpacesToReadContinuouslyPtr++;               
                    if(RegisterSpacesToReadContinuouslyPtr >= RegisterSpacesToReadContinuously.length) {
                        RegisterSpacesToReadContinuouslyPtr = 0;
                        currentinverter++
                        if(currentinverter > ModBusIDs.length){
                            currentinverter = 1;  
                            triggerprocessing = 1;                    
                        }
                    }     
                    

                    }, 2000);

                    Wäre schön wenn mir da jemand helfen könnte.

                    T 1 Antwort Letzte Antwort
                    0
                    • W WILHER

                      Hallo zusammen, versuche auch meinen SUN2000 ausgelesen zu bekommen, leider funktioniert es nicht. Es werde auch irgendwie keine Werte geschrieben. Habe 1 String, 1 Batteriespeicher LUNA2000 10kw. Was fehlt hier ggf noch?

                      // 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.10.101", { port: 502 });
                      // Enter the Modbus-IDs of your Sun2000 inverters here:
                      const ModBusIDs = [16, 1];
                      // On which Modbus-ID can we reach the power meter? (via Sun2000!)
                      const PowerMeterID = 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, 2], [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(objectname)) {
                      createState(objectname, value, options);
                      }
                      else {
                      setState(objectname, value);
                      }
                      }
                      // ---------------------------------------------------------------
                      // Functions to map registers into ioBreaker objects:
                      function processOptimizers(id) {
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerTotalNumber", getU16(GlobalDataBuffer[id-1], 35200), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerOnlineNumber", getU16(GlobalDataBuffer[id-1], 35201), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerFeatureData", getU16(GlobalDataBuffer[id-1], 35202), {name: "", unit: ""});
                      }

                      function processInverterPowerAdjustments(id) {
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementMode", getU16(GlobalDataBuffer[id-1], 35300), {name: "", unit: ""});
                      forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementCommand", getU16(GlobalDataBuffer[id-1], 35303), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementMode", getU16(GlobalDataBuffer[id-1], 35304), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementValue", getU32(GlobalDataBuffer[id-1], 35305), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementCommand",getU16(GlobalDataBuffer[id-1], 35307), {name: "", unit: ""});
                      forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RunningStatus", getU16(GlobalDataBuffer[id-1], 37000), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.ChargeAndDischargePower",getI32(GlobalDataBuffer[id-1], 37001), {name: "Charge and Discharge Power", unit: "W"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BusVoltage", getU16(GlobalDataBuffer[id-1], 37003) / 10, {name: "Busvoltage", unit: "V"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BatterySOC", getU16(GlobalDataBuffer[id-1], 37004) / 10, {name: "Battery SOC", unit: "%"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.WorkingMode", getU16(GlobalDataBuffer[id-1], 37006), {name: "Working Mode", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RatedChargePower", getU32(GlobalDataBuffer[id-1], 37007), {name: "", unit: "W"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RatedDischargePower", getU32(GlobalDataBuffer[id-1], 37009), {name: "", unit: "W"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.FaultID", getU16(GlobalDataBuffer[id-1], 37014), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayChargeCapacity", getU32(GlobalDataBuffer[id-1], 37015) / 100, {name: "", unit: "kWh"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37017) / 100, {name: "", unit: "kWh"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BusCurrent", getI16(GlobalDataBuffer[id-1], 37021) / 10, {name: "Buscurrent", unit: "A"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BatteryTemperature", getI16(GlobalDataBuffer[id-1], 37022) / 10, {name: "Battery Temperatue", unit: "°C"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RemainingChargeDischargeTime", getU16(GlobalDataBuffer[id-1], 37025), {name: "", unit: "mins"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.DCDCversion", getZeroTerminatedString(GlobalDataBuffer[id-1], 37026, 10), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BMSversion", getZeroTerminatedString(GlobalDataBuffer[id-1], 37036, 10), {name: "", unit: ""});
                      }
                      // Battery registers 16+17 (Storage-related)
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.MaximumChargePower", getU32(GlobalDataBuffer[id-1], 37046), {name: "", unit: "W"});
                      forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.SN",                         getZeroTerminatedString(GlobalDataBuffer[id-1], 37052, 10), {name: "Serialnumber", unit: ""});       
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.TotalCharge",                getU32(GlobalDataBuffer[id-1], 37066) / 100, {name: "", unit: "kWh"});
                      forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.SN",                     getZeroTerminatedString(GlobalDataBuffer[id-1], 37700, 10), {name: "Serialnumber", unit: ""});        
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BatterySOC",             getU16(GlobalDataBuffer[id-1], 37738) / 10, {name: "", unit: "%"});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.RunningStatus",          getU16(GlobalDataBuffer[id-1], 37741), {name: "", unit: ""});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.ChargeAndDischargePower",getI32(GlobalDataBuffer[id-1], 37743), {name: "", unit: "W"});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayChargeCapacity",    getU32(GlobalDataBuffer[id-1], 37746) / 100, {name: "", unit: "kWh"});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37748) / 100, {name: "", unit: "kWh"});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BusVoltage",             getU16(GlobalDataBuffer[id-1], 37750) / 10, {name: "", unit: "V"});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BusCurrent",             getI16(GlobalDataBuffer[id-1], 37751) / 10, {name: "", unit: "A"});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BatteryTemperature",     getI16(GlobalDataBuffer[id-1], 37752) / 10, {name: "", unit: "°C"});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.TotalCharge",                 getU32(GlobalDataBuffer[id-1], 37753) / 100, {name: "", unit: "kWh"});
                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.TotalDischarge",              getU32(GlobalDataBuffer[id-1], 37755) / 100, {name: "", unit: "kWh"});
                      }
                      // Battery register 32-41 (Storage related)
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.RatedCapacity", getU32(GlobalDataBuffer[id-1], 37758) / 1, {name: "", unit: "Wh"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.SOC", getU16(GlobalDataBuffer[id-1], 37760) / 10, {name: "", unit: "%"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.RunningStatus", getU16(GlobalDataBuffer[id-1], 37762) / 1, {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.BusVoltage", getU16(GlobalDataBuffer[id-1], 37763) / 10, {name: "", unit: "V"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.BusCurrent", getI16(GlobalDataBuffer[id-1], 37764) / 10, {name: "", unit: "A"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 37765) / 1, {name: "", unit: "W"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.TotalCharge", getU32(GlobalDataBuffer[id-1], 37780) / 100, {name: "", unit: "kWh"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.TotalDischarge", getU32(GlobalDataBuffer[id-1], 37782) / 100, {name: "", unit: "kWh"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.CurrentDayChargeCapacity", getU32(GlobalDataBuffer[id-1], 37784) / 100, {name: "", unit: "kWh"});
                      forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.SoftwareVersion",    getZeroTerminatedString(GlobalDataBuffer[id-1], 37814, 8), {name: "Softwareversion", unit: ""});
                      }
                      if(BatteryUnits[id-1][0] > 0) {
                          forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".SN",                getZeroTerminatedString(GlobalDataBuffer[id-1], 38200+(i-1)*126+(j-1)*42, 6), {name: "", unit: ""});
                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".FirmwareVersion",   getZeroTerminatedString(GlobalDataBuffer[id-1], 38210+(i-1)*126+(j-1)*42, 8), {name: "", unit: ""});
                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".WorkingStatus",     getU16(GlobalDataBuffer[id-1], 38228+(i-1)*126+(j-1)*42), {name: "", unit: ""});
                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".BatterySOC",        getU16(GlobalDataBuffer[id-1], 38229+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "%"});
                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 38233+(i-1)*126+(j-1)*42) / 1000, {name: "", unit: "kW"});
                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Voltage",           getU16(GlobalDataBuffer[id-1], 38235+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "V"});
                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Current",           getI16(GlobalDataBuffer[id-1], 38236+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "A"});
                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".TotalCharge",       getU32(GlobalDataBuffer[id-1], 38238+(i-1)*126+(j-1)*42) / 100, {name: "", unit: "kWh"});
                                  forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".MaxTemperature", getI16(GlobalDataBuffer[id-1], 38452+(i-1)*6+(j-1)*2) / 10, {name: "", unit: "°C"});
                                  createState("Solarpower.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("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], 32001), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".State3", getU16(GlobalDataBuffer[id-1], 32002), {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 + ".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", getU16(GlobalDataBuffer[id-1], 32091), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".ShutdownTime", getU16(GlobalDataBuffer[id-1], 32093), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".AccomulatedEnergyYield", getU16(GlobalDataBuffer[id-1], 32106), {name: "", unit: "kWh"});
                      forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Model", getZeroTerminatedString(GlobalDataBuffer[id-1], 30000, 8), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".SN", getZeroTerminatedString(GlobalDataBuffer[id-1], 30015, 6), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".PN", getZeroTerminatedString(GlobalDataBuffer[id-1], 30025, 6), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".ModelID", getU16(GlobalDataBuffer[id-1], 30070), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".PVStrings", getU16(GlobalDataBuffer[id-1], 30071), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".MPPTrackers", getU16(GlobalDataBuffer[id-1], 30072), {name: "", unit: ""});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxRatedPower", getU32(GlobalDataBuffer[id-1], 30073) / 1000, {name: "", unit: "kW"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxActivePower", getU32(GlobalDataBuffer[id-1], 30075) / 1000, {name: "", unit: "kW"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxApparentPower", getU32(GlobalDataBuffer[id-1], 30077) / 1000, {name: "", unit: "kVA"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxReactivePowerToGrid", getI32(GlobalDataBuffer[id-1], 30079) / 1000, {name: "", unit: "kVAr"});
                      forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxReactivePowerFromGrid", getI32(GlobalDataBuffer[id-1], 30081) / 1000, {name: "", unit: "kVAr"});
                      }

                      function readRegisterSpace(id, address, length) {
                      client.setID(ModBusIDs[id-1]);
                      client.readHoldingRegisters(address, length, function(err, data) {
                      if (err) {
                      console.warn("Error received reading address " + address + " from id: " + ModBusIDs[id-1] + " with error: " + modbusErrorMessages[err.modbusCode]);
                      }
                      else
                      {
                      console.debug("Read data from id/address " + ModBusIDs[id-1] + "/" + address + "\nData is: " + data.data);
                      for(var i = 0; i < length; i++) {
                      GlobalDataBuffer[id-1][address+i] = data.data[i];
                      }
                      }
                      });
                      }

                      function processData() {
                      console.log("Processing new data...");
                      for(var i = 1; i <= ModBusIDs.length; i++) {
                      ProcessDeviceInfo(i);
                      processInverterStatus(i);
                      processBattery(i);
                      processInverterPowerAdjustments(i);
                      processOptimizers(i);
                      }
                      ProcessPowerMeterStatus();
                      console.log("Processing done!");
                      }

                      // -------------------------------------------------------------------
                      // This is the main function triggering a read via modbus-tcp every two seconds.
                      // Processing of data is triggered as soon as one complete set of registers is copied.
                      var triggerprocessing = 0;
                      var currentinverter = 1;

                      setInterval(function() {
                      if(triggerprocessing == 1) {
                      triggerprocessing = 0;
                      processData();
                      }

                      console.log("Triggering read of inverter " + currentinverter + " at address " + RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0] + " with length " +  RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]);
                      readRegisterSpace(currentinverter, RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0], RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]); 
                      RegisterSpacesToReadContinuouslyPtr++;               
                      if(RegisterSpacesToReadContinuouslyPtr >= RegisterSpacesToReadContinuously.length) {
                          RegisterSpacesToReadContinuouslyPtr = 0;
                          currentinverter++
                          if(currentinverter > ModBusIDs.length){
                              currentinverter = 1;  
                              triggerprocessing = 1;                    
                          }
                      }     
                      

                      }, 2000);

                      Wäre schön wenn mir da jemand helfen könnte.

                      T Offline
                      T Offline
                      Thomas42
                      schrieb am zuletzt editiert von
                      #47

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

                      1 Antwort Letzte Antwort
                      0
                      • oswibzO oswibz

                        @zoid1988 Hallo zusammen, gibt es hier Neuigkeiten. Hab heute mein WR angeschlossen. Datenpunkte wurden generiert aber erhalte den selben Fehler. Gibt es Lösungen? Danke an alle für die Hilfe!

                        Ich habe auch den Workaround eingesetzt, erhalte immer aber die gleiche Warnung:
                        21:02:25.393 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 30000 with length 81
                        21:02:25.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 30000 from id: 1 with error: undefined
                        21:02:27.393 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37100 with length 114
                        21:02:27.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37100 from id: 1 with error: undefined
                        21:02:29.394 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 32000 with length 116
                        21:02:29.394 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 32000 from id: 1 with error: undefined
                        21:02:31.394 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37000 with length 68
                        21:02:31.395 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37000 from id: 1 with error: undefined
                        21:02:33.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37700 with length 100
                        21:02:33.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37700 from id: 1 with error: undefined
                        21:02:35.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 37800 with length 100
                        21:02:35.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 37800 from id: 1 with error: undefined
                        21:02:37.395 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38200 with length 100
                        21:02:37.396 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38200 from id: 1 with error: undefined
                        21:02:39.406 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38300 with length 100
                        21:02:39.406 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38300 from id: 1 with error: undefined
                        21:02:41.406 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 38400 with length 100
                        21:02:41.407 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 38400 from id: 1 with error: undefined
                        21:02:43.407 info javascript.0 (23379) script.js.Test.PV-Test: Triggering read of inverter 1 at address 35300 with length 40
                        21:02:43.408 warn javascript.0 (23379) script.js.Test.PV-Test: Error received reading address 35300 from id: 1 with error: undefined

                        ? Offline
                        ? Offline
                        Ein ehemaliger Benutzer
                        schrieb am zuletzt editiert von
                        #48

                        @oswibz

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

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

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

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

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

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

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

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

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

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

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

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

                          ForceSetState("Solarpower.Huawei.Inverter." + id + ".StartupTime",              new Date(GetU32(globalDataBuffer[id-1], 32091)*1000),          {name: "", unit: ""});
                          ForceSetState("Solarpower.Huawei.Inverter." + id + ".ShutdownTime",             new Date(GetU32(globalDataBuffer[id-1], 32093)*1000),          {name: "", unit: ""});
                          
                          S 1 Antwort Letzte Antwort
                          0
                          • Alex WarkentinA Alex Warkentin

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

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

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

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

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

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

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

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

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

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

                            ForceSetState("Solarpower.Huawei.Inverter." + id + ".StartupTime",              new Date(GetU32(globalDataBuffer[id-1], 32091)*1000),          {name: "", unit: ""});
                            ForceSetState("Solarpower.Huawei.Inverter." + id + ".ShutdownTime",             new Date(GetU32(globalDataBuffer[id-1], 32093)*1000),          {name: "", unit: ""});
                            
                            S Offline
                            S Offline
                            striegel26
                            schrieb am zuletzt editiert von striegel26
                            #50

                            Hallo zusammen

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

                            VG Dennis

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

                              Hallo zusammen

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

                              VG Dennis

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

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

                              Was sagen denn deine Protokolle?

                              S 1 Antwort Letzte Antwort
                              0
                              • Alex WarkentinA Alex Warkentin

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

                                Was sagen denn deine Protokolle?

                                S Offline
                                S Offline
                                striegel26
                                schrieb am zuletzt editiert von striegel26
                                #52

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

                                Alex WarkentinA 1 Antwort Letzte Antwort
                                0
                                • S striegel26

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

                                  Alex WarkentinA Offline
                                  Alex WarkentinA Offline
                                  Alex Warkentin
                                  schrieb am zuletzt editiert von
                                  #53

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

                                  S 1 Antwort Letzte Antwort
                                  0
                                  • Alex WarkentinA Alex Warkentin

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

                                    S Offline
                                    S Offline
                                    striegel26
                                    schrieb am zuletzt editiert von
                                    #54

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

                                    1 Antwort Letzte Antwort
                                    0
                                    • J Offline
                                      J Offline
                                      juggi1962
                                      schrieb am zuletzt editiert von
                                      #55

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

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

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

                                        
                                        javascript.0
                                        2023-03-05 09:56:27.826	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38200 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:25.826	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37800 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:23.824	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37700 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:21.826	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37000 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:19.823	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 32000 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:17.823	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37100 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:15.823	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 30000 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:13.821	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 35300 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:11.820	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38400 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:09.820	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38300 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:07.819	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38200 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:05.819	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37800 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:03.820	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37700 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:56:01.819	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37000 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:59.817	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 32000 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:57.817	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37100 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:55.817	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 30000 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:53.817	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 35300 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:51.818	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38400 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:49.816	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38300 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:47.816	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 38200 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:45.815	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37800 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:43.815	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37700 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:41.815	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37000 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:39.815	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 32000 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:37.814	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 37100 from id: undefined with error: undefined
                                        
                                        javascript.0
                                        2023-03-05 09:55:35.814	warn	script.js.Test.Modbus_Huawei_Sun_2000: Error received reading address 30000 from id: undefined with error: undefined
                                        
                                        A Offline
                                        A Offline
                                        ATARI
                                        schrieb am zuletzt editiert von ATARI
                                        #56

                                        @juggi1962

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

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

                                        Gruß
                                        ATARI

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

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

                                        J 1 Antwort Letzte Antwort
                                        0
                                        • K Kachel

                                          Die Modbus-Ansteuerung vom Huawei Sun2000 Wechselrichter ist über TCP etwas speziell, da nach öffnen des TCP-Ports noch eine Pause eingehalten werden muss, da sonst keine Daten zurück geliefert werden. Auch wird nicht jede Modbus-TCP-Anfrage mit den angeforderten Registern beantwortet. Daher funktioniert die Kommunikation über den normalen Modbus-Adapter im ioBroker nicht.

                                          Um die verfügbaren Register in den ioBroker zu bekommen hab ich ein js-script geschrieben, dass die Abfrage der Register über TCP macht und die Daten entsprechend parsed. Man braucht dafür im IOBroker nur die ScriptEngine und muss in deren Settings noch die modbus-serial hinzufügen. Danach legt das Script einen großen Satz an Objekten an und aktualisiert die regelmäßig (ca. 2x die Minute). Es werden nur Register gelesen - das Schreiben von Registern ist nicht eingebaut (und bei mir gerade auch nicht nötig). Damit die Netzwerkpakete möglichst groß sind werden die Registern in Blöcken abgefragt.

                                          Wer möchte kann das Script gerne nutzen. . Einfach IP, Batteriekonfiguration und die Modbus-IDs eintragen und ausführen. Wer es ändern möchte darf dies auch gerne tun - es freut aber sicher alle ioBroker-Nutzer wenn ihr Änderungen auch wieder veröffentlicht.

                                          Falls jemand noch eine Idee hat, wie man den Huawei File-transfer über Modbus implementieren kann (mit deren speziellem function-code 0x41), würde ich mich freuen. Der fehlt leider damit die Optimierer ihre Echtzeit-Daten in den IOBroker liefern können...

                                          der Kachel

                                          // 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("$$$ADD.YOUR.IP.HERE$$$", { port: 502 });
                                          // Enter the Modbus-IDs of your Sun2000 inverters here:
                                          const ModBusIDs = [16, 1];
                                          // On which Modbus-ID can we reach the power meter? (via Sun2000!)
                                          const PowerMeterID = 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(objectname)) {
                                                  createState(objectname, value, options);        
                                              }
                                              else {
                                                  setState(objectname, value);
                                              }
                                          }  
                                          // ---------------------------------------------------------------
                                          // Functions to map registers into ioBreaker objects:
                                          function processOptimizers(id) {
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerTotalNumber",     getU16(GlobalDataBuffer[id-1], 35200), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerOnlineNumber",    getU16(GlobalDataBuffer[id-1], 35201), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerFeatureData",     getU16(GlobalDataBuffer[id-1], 35202), {name: "", unit: ""});
                                          }
                                          
                                          function processInverterPowerAdjustments(id) {
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementMode",     getU16(GlobalDataBuffer[id-1], 35300), {name: "", unit: ""});
                                              forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementCommand",  getU16(GlobalDataBuffer[id-1], 35303), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementMode",   getU16(GlobalDataBuffer[id-1], 35304), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementValue",  getU32(GlobalDataBuffer[id-1], 35305), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementCommand",getU16(GlobalDataBuffer[id-1], 35307), {name: "", unit: ""});
                                              forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RunningStatus",          getU16(GlobalDataBuffer[id-1], 37000), {name: "", unit: ""});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.ChargeAndDischargePower",getI32(GlobalDataBuffer[id-1], 37001), {name: "Charge and Discharge Power", unit: "W"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BusVoltage",             getU16(GlobalDataBuffer[id-1], 37003) / 10, {name: "Busvoltage", unit: "V"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BatterySOC",             getU16(GlobalDataBuffer[id-1], 37004) / 10, {name: "Battery SOC", unit: "%"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.WorkingMode",            getU16(GlobalDataBuffer[id-1], 37006), {name: "Working Mode", unit: ""});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RatedChargePower",       getU32(GlobalDataBuffer[id-1], 37007), {name: "", unit: "W"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RatedDischargePower",    getU32(GlobalDataBuffer[id-1], 37009), {name: "", unit: "W"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.FaultID",                getU16(GlobalDataBuffer[id-1], 37014), {name: "", unit: ""});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayChargeCapacity",    getU32(GlobalDataBuffer[id-1], 37015) / 100, {name: "", unit: "kWh"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37017) / 100, {name: "", unit: "kWh"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BusCurrent",             getI16(GlobalDataBuffer[id-1], 37021) / 10, {name: "Buscurrent", unit: "A"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BatteryTemperature",     getI16(GlobalDataBuffer[id-1], 37022) / 10, {name: "Battery Temperatue", unit: "°C"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RemainingChargeDischargeTime", getU16(GlobalDataBuffer[id-1], 37025), {name: "", unit: "mins"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.DCDCversion",            getZeroTerminatedString(GlobalDataBuffer[id-1], 37026, 10), {name: "", unit: ""});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BMSversion",             getZeroTerminatedString(GlobalDataBuffer[id-1], 37036, 10), {name: "", unit: ""});
                                              }
                                              // Battery registers 16+17 (Storage-related)
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.MaximumChargePower",                getU32(GlobalDataBuffer[id-1], 37046), {name: "", unit: "W"});
                                              forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.SN",                         getZeroTerminatedString(GlobalDataBuffer[id-1], 37052, 10), {name: "Serialnumber", unit: ""});       
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.TotalCharge",                getU32(GlobalDataBuffer[id-1], 37066) / 100, {name: "", unit: "kWh"});
                                              forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.SN",                     getZeroTerminatedString(GlobalDataBuffer[id-1], 37700, 10), {name: "Serialnumber", unit: ""});        
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BatterySOC",             getU16(GlobalDataBuffer[id-1], 37738) / 10, {name: "", unit: "%"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.RunningStatus",          getU16(GlobalDataBuffer[id-1], 37741), {name: "", unit: ""});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.ChargeAndDischargePower",getI32(GlobalDataBuffer[id-1], 37743), {name: "", unit: "W"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayChargeCapacity",    getU32(GlobalDataBuffer[id-1], 37746) / 100, {name: "", unit: "kWh"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37748) / 100, {name: "", unit: "kWh"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BusVoltage",             getU16(GlobalDataBuffer[id-1], 37750) / 10, {name: "", unit: "V"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BusCurrent",             getI16(GlobalDataBuffer[id-1], 37751) / 10, {name: "", unit: "A"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BatteryTemperature",     getI16(GlobalDataBuffer[id-1], 37752) / 10, {name: "", unit: "°C"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.TotalCharge",                 getU32(GlobalDataBuffer[id-1], 37753) / 100, {name: "", unit: "kWh"});
                                                  forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.TotalDischarge",              getU32(GlobalDataBuffer[id-1], 37755) / 100, {name: "", unit: "kWh"});
                                              }
                                              // Battery register 32-41 (Storage related)
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.RatedCapacity", getU32(GlobalDataBuffer[id-1], 37758) / 1, {name: "", unit: "Wh"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.SOC", getU16(GlobalDataBuffer[id-1], 37760) / 10, {name: "", unit: "%"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.RunningStatus", getU16(GlobalDataBuffer[id-1], 37762) / 1, {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.BusVoltage", getU16(GlobalDataBuffer[id-1], 37763) / 10, {name: "", unit: "V"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.BusCurrent", getI16(GlobalDataBuffer[id-1], 37764) / 10, {name: "", unit: "A"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 37765) / 1, {name: "", unit: "W"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.TotalCharge", getU32(GlobalDataBuffer[id-1], 37780) / 100, {name: "", unit: "kWh"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.TotalDischarge", getU32(GlobalDataBuffer[id-1], 37782) / 100, {name: "", unit: "kWh"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.CurrentDayChargeCapacity", getU32(GlobalDataBuffer[id-1], 37784) / 100, {name: "", unit: "kWh"});
                                              forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.SoftwareVersion",    getZeroTerminatedString(GlobalDataBuffer[id-1], 37814, 8), {name: "Softwareversion", unit: ""});
                                              }
                                              if(BatteryUnits[id-1][0] > 0) {
                                                  forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".SN",                getZeroTerminatedString(GlobalDataBuffer[id-1], 38200+(i-1)*126+(j-1)*42, 6), {name: "", unit: ""});
                                                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".FirmwareVersion",   getZeroTerminatedString(GlobalDataBuffer[id-1], 38210+(i-1)*126+(j-1)*42, 8), {name: "", unit: ""});
                                                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".WorkingStatus",     getU16(GlobalDataBuffer[id-1], 38228+(i-1)*126+(j-1)*42), {name: "", unit: ""});
                                                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".BatterySOC",        getU16(GlobalDataBuffer[id-1], 38229+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "%"});
                                                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 38233+(i-1)*126+(j-1)*42) / 1000, {name: "", unit: "kW"});
                                                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Voltage",           getU16(GlobalDataBuffer[id-1], 38235+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "V"});
                                                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Current",           getI16(GlobalDataBuffer[id-1], 38236+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "A"});
                                                          forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".TotalCharge",       getU32(GlobalDataBuffer[id-1], 38238+(i-1)*126+(j-1)*42) / 100, {name: "", unit: "kWh"});
                                                          forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".MaxTemperature", getI16(GlobalDataBuffer[id-1], 38452+(i-1)*6+(j-1)*2) / 10, {name: "", unit: "°C"});
                                                          createState("Solarpower.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("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], 32001), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".State3", getU16(GlobalDataBuffer[id-1], 32002), {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 + ".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",               getU16(GlobalDataBuffer[id-1], 32091), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".ShutdownTime",              getU16(GlobalDataBuffer[id-1], 32093), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".AccomulatedEnergyYield",    getU16(GlobalDataBuffer[id-1], 32106), {name: "", unit: "kWh"});
                                              forcesetState("Solarpower.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("Solarpower.Huawei.Inverter." + id + ".Model",  getZeroTerminatedString(GlobalDataBuffer[id-1], 30000, 8), {name: "", unit: ""}); 
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".SN",     getZeroTerminatedString(GlobalDataBuffer[id-1], 30015, 6), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".PN",     getZeroTerminatedString(GlobalDataBuffer[id-1], 30025, 6), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".ModelID",           getU16(GlobalDataBuffer[id-1], 30070), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".PVStrings",         getU16(GlobalDataBuffer[id-1], 30071), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".MPPTrackers",       getU16(GlobalDataBuffer[id-1], 30072), {name: "", unit: ""});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxRatedPower",     getU32(GlobalDataBuffer[id-1], 30073) / 1000, {name: "", unit: "kW"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxActivePower",    getU32(GlobalDataBuffer[id-1], 30075) / 1000, {name: "", unit: "kW"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxApparentPower",  getU32(GlobalDataBuffer[id-1], 30077) / 1000, {name: "", unit: "kVA"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxReactivePowerToGrid",        getI32(GlobalDataBuffer[id-1], 30079) / 1000, {name: "", unit: "kVAr"});
                                              forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxReactivePowerFromGrid",      getI32(GlobalDataBuffer[id-1], 30081) / 1000, {name: "", unit: "kVAr"});
                                          }
                                          
                                          function readRegisterSpace(id, address, length) {
                                              client.setID(ModBusIDs[id-1]);
                                              client.readHoldingRegisters(address, length, function(err, data) {
                                                  if (err) {
                                                      console.warn("Error received reading address " + address + " from id: " + ModBusIDs[id-1] + " with error: " + modbusErrorMessages[err.modbusCode]);            
                                                  }
                                                  else
                                                  {   
                                                      console.debug("Read data from id/address " + ModBusIDs[id-1] + "/" + address + "\nData is: " + data.data);
                                                      for(var i = 0; i < length; i++)  {
                                                          GlobalDataBuffer[id-1][address+i] = data.data[i];
                                                      } 
                                                  }
                                              });
                                          }
                                          
                                          function processData() {
                                              console.log("Processing new data...");
                                              for(var i = 1; i <= ModBusIDs.length; i++) {
                                                  ProcessDeviceInfo(i);
                                                  processInverterStatus(i);
                                                  processBattery(i);
                                                  processInverterPowerAdjustments(i);
                                                  processOptimizers(i); 
                                              }    
                                              ProcessPowerMeterStatus();
                                              console.log("Processing done!");
                                          }
                                          
                                          
                                          // -------------------------------------------------------------------
                                          // This is the main function triggering a  read via modbus-tcp every two seconds.
                                          // Processing of data is triggered as soon as one complete set of registers is copied.
                                          var triggerprocessing = 0; 
                                          var currentinverter = 1;
                                          
                                          
                                          setInterval(function() {
                                              if(triggerprocessing == 1) {
                                                  triggerprocessing = 0;
                                                  processData();        
                                              }      
                                             
                                              console.log("Triggering read of inverter " + currentinverter + " at address " + RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0] + " with length " +  RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]);
                                              readRegisterSpace(currentinverter, RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0], RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]); 
                                              RegisterSpacesToReadContinuouslyPtr++;               
                                              if(RegisterSpacesToReadContinuouslyPtr >= RegisterSpacesToReadContinuously.length) {
                                                  RegisterSpacesToReadContinuouslyPtr = 0;
                                                  currentinverter++
                                                  if(currentinverter > ModBusIDs.length){
                                                      currentinverter = 1;  
                                                      triggerprocessing = 1;                    
                                                  }
                                              }     
                                          }, 2000);
                                          
                                          A Offline
                                          A Offline
                                          ATARI
                                          schrieb am zuletzt editiert von ATARI
                                          #57

                                          @kachel

                                          Vielen Dank für das Script und Deine Arbeit !

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

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

                                          Gruß
                                          ATARI

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

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

                                          Alex WarkentinA J H 3 Antworten 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

                                          523

                                          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