Navigation

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

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    Huawei Sun2000 & ioBroker via JS script funktioniert

    This topic has been deleted. Only users with topic management privileges can see it.
    • Alex Warkentin
      Alex Warkentin @juggi1962 last edited by

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

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

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

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

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

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

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

            @juggi1962

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

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

            Gruß
            ATARI

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

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

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

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

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

                @alex-warkentin
                Super Danke, werde ich gleich probieren

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

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

                  @kachel

                  Vielen Dank für das Script und Deine Arbeit !

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

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

                  Gruß
                  ATARI

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

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

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

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

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

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

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

                      @juggi1962 Poste mal die Logs, wenn der Fehler auftritt

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

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

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

                        @juggi1962 Poste mal die Logs, wenn der Fehler auftritt

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

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

                        Super Danke.
                        Hab eh keine Batterie. Werde es gleich testen.
                        Gruß Jürgen

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

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

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

                          @juggi1962 Poste mal die Logs, wenn der Fehler auftritt

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

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

                          Super Danke.
                          Hab eh keine Batterie. Werde es gleich testen.
                          Gruß Jürgen

                          Guten Morgen soweit läuft es mal, aber kann es sein, dass bei
                          Solarpower Huawei Inverter 1 AccomulatedEnergyYield und
                          Solarpower.Huawei.Inverter.1.DailyEnergyYield
                          das Komma fehlt, denn der Tägliche Ertrag wäre schön aber nicht war 🙂
                          kann man das irgend wie ändern?

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

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

                            @juggi1962 Poste mal die Logs, wenn der Fehler auftritt

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

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

                            So der Fehler ist wieder da, die Freude hat nicht lange angehalten.
                            Hier die Logs vom Fehler, nach Neustart des Skrips läufts wieder 😞

                            
                            
                            javascript.0
                            2023-03-06 10:27:26.845	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 32000 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:27:23.846	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 37100 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:27:20.841	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 32000 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:27:17.842	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 37100 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:27:14.840	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 32000 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:27:11.842	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 37100 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:27:08.839	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 32000 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:27:05.841	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 37100 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:27:02.838	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 32000 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:26:59.839	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 37100 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:26:56.837	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 32000 from id: 1 with error: undefined
                            
                            javascript.0
                            2023-03-06 10:26:53.840	warn	script.js.Neu.PV_Anlage.Modbus_Huawei_Sun2000_neu: Error received reading address 37100 from id: 1 with error: undefined
                            
                            1 Reply Last reply Reply Quote 0
                            • Alex Warkentin
                              Alex Warkentin @juggi1962 last edited by

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

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

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

                              @juggi1962 Poste mal die Logs, wenn der Fehler auftritt

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

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

                              Super Danke.
                              Hab eh keine Batterie. Werde es gleich testen.
                              Gruß Jürgen

                              Guten Morgen soweit läuft es mal, aber kann es sein, dass bei
                              Solarpower Huawei Inverter 1 AccomulatedEnergyYield und
                              Solarpower.Huawei.Inverter.1.DailyEnergyYield
                              das Komma fehlt, denn der Tägliche Ertrag wäre schön aber nicht war 🙂
                              kann man das irgend wie ändern?

                              Diese Werte habe ich mir noch gar nicht angeschaut. Hier fehlt im Script (Zeilen 193 und 194) tatsächlich der Multiplikator.

                              ForceSetState("Solarpower.Huawei.Inverter." + id + ".AccomulatedEnergyYield",   GetU32(globalDataBuffer[id-1], 32106) / 100,          {name: "", unit: "kWh"});
                                  ForceSetState("Solarpower.Huawei.Inverter." + id + ".DailyEnergyYield",         GetU32(globalDataBuffer[id-1], 32114) / 100,          {name: "", unit: "kWh"});
                              

                              Zu deinem Hauptproblem: Ich bin mir aktuell nicht ganz sicher, ob die Wiederverbindung im Script korrekt funktioniert. Ich habe bisher nur das Netzwerkkabel des ioBrokers für 10 Sekunden gezogen und das machte ihm nichts aus. Aber die Meldung, die bei einer neuen Verbindung geloggt werden sollten, kamen nicht. Daher kann es gut sein, dass client.isOpen vielleicht gar nicht so funktioniert wie erhofft.

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

                                @alex-warkentin
                                Danke für deine Bemühungen und für die Richtigstellung der Multiplikatoren 👍
                                Kannst du das mit dem client.isOpen vielleicht testen und verbessern, das wäre echt super.
                                Ich kenne mich leider mit JS gar nicht aus.
                                Danke im Voraus, Gruß Jürgen

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

                                  @juggi1962
                                  Ich bin aktuell beruflich ziemlich eingespannt, aber mich interessiert das auch. Ich werde das bei Gelegenheit mal genauer anschauen.

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

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

                                    @alex-warkentin
                                    Danke für deine Bemühungen und für die Richtigstellung der Multiplikatoren 👍
                                    Kannst du das mit dem client.isOpen vielleicht testen und verbessern, das wäre echt super.
                                    Ich kenne mich leider mit JS gar nicht aus.
                                    Danke im Voraus, Gruß Jürgen

                                    isOpen soll laut Doku eigentlich ein Funktion an. Wird aber als solche nicht zur Verfügung gestellt und ist sonst auch immer true. Probiere bitte dein Script mit folgendem Snippet ab Zeile 197 zu überschreiben. Nun frage ich den ErrorCode nach null ab und reconnecte dann.

                                    function ReadRegisterSpace(id, address, length) {
                                        client.setID(modbusID[id-1]);
                                        client.readHoldingRegisters(address, length, function(err, data) {
                                            if (err) {
                                                if (err.modbusCode == null) {
                                                    console.warn("Lost connection to client. Trying to reconnect...");
                                                    ConnectModbus();
                                                } 
                                                else console.warn("Error received reading address " + address + " from id: " + modbusID[id-1] + " with error: " + modbusErrorMessages[err.modbusCode]); 
                                            }
                                            else
                                            {   
                                                console.debug("Read data from id/address " + modbusID[id-1] + "/" + address + "\nData is: " + data.data);
                                                for(var i = 0; i < length; i++)  {
                                                    globalDataBuffer[id-1][address+i] = data.data[i];
                                                } 
                                            }
                                        });
                                    }
                                    
                                    function ProcessData() {
                                        //console.log("Processing new data...");
                                        for(var i = 1; i <= modbusID.length; i++) {
                                            ProcessInverterStatus(i);
                                        }    
                                        ProcessPowerMeterStatus();
                                        //console.log("Processing done!");
                                    }
                                    
                                    
                                    // -------------------------------------------------------------------
                                    // This is the main function triggering a  read via modbus-tcp every two seconds.
                                    // Processing of data is triggered as soon as one complete set of registers is copied.
                                    var triggerprocessing = 0; 
                                    var currentinverter = 1;
                                    
                                    
                                    setInterval(function() {
                                        if(triggerprocessing == 1) {
                                            triggerprocessing = 0;
                                            ProcessData();        
                                        }      
                                       
                                        //console.log("Triggering read of inverter " + currentinverter + " at address " + registerSpacesToReadContinuously[registerSpacesToReadContinuouslyPtr][0] + " with length " +  registerSpacesToReadContinuously[registerSpacesToReadContinuouslyPtr][1]);
                                        ReadRegisterSpace(currentinverter, registerSpacesToReadContinuously[registerSpacesToReadContinuouslyPtr][0], registerSpacesToReadContinuously[registerSpacesToReadContinuouslyPtr][1]); 
                                        registerSpacesToReadContinuouslyPtr++;               
                                        if(registerSpacesToReadContinuouslyPtr >= registerSpacesToReadContinuously.length) {
                                            registerSpacesToReadContinuouslyPtr = 0;
                                            currentinverter++
                                            if(currentinverter > modbusID.length){
                                                currentinverter = 1;  
                                                triggerprocessing = 1;                    
                                            }
                                        }     
                                    }, 3000);
                                    

                                    Du solltest aber trotzdem versuchen zu ergründen, warum die ständigen Verbindungsabbrüche kommen. Falls möglich vielleicht das Ethernet-Kabel tauschen.

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

                                      @alex-warkentin
                                      Hallo und noch mal danke für deine Bemühungen.
                                      Leider gibt es immer noch die selben Fehlermeldungen, bis jetzt immer mal einzelne,
                                      mal schauen ob es wieder dauerhaft wird.
                                      Ich habe jetzt für eine Stunde einen Ping laufen lassen und hatte beim Ping keine Abbrüche aber im Skript 10 Fehler.
                                      Lankabel wurde vorher gegen ein neues getauscht.
                                      Hmmmmm komisch 😞

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

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

                                        @alex-warkentin
                                        Hallo und noch mal danke für deine Bemühungen.
                                        Leider gibt es immer noch die selben Fehlermeldungen, bis jetzt immer mal einzelne,
                                        mal schauen ob es wieder dauerhaft wird.
                                        Ich habe jetzt für eine Stunde einen Ping laufen lassen und hatte beim Ping keine Abbrüche aber im Skript 10 Fehler.
                                        Lankabel wurde vorher gegen ein neues getauscht.
                                        Hmmmmm komisch 😞

                                        Naja, jetzt müsste die Fehlermeldung "Lost connection...." lauten. Und danach die Verbindung neu aufgebaut werden. Dann funktioniert das Script erwartungsgemäß.

                                        Wie ist es denn mit deiner ioBroker Hardware? Kann es sein, dass hier die Abbrüche stattfinden?

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

                                          @alex-warkentin
                                          Die Fehlermeldung Lost connection... kommt nur wenn ich das LAN Kabel ziehe.
                                          Mein Raspberry und IoBroker laufen ohne Aussetzer.
                                          Diese Fehlermeldungen auch mit 32000 kommen immer mal wieder, hören aber dazwischen wieder auf.
                                          Gruß Jürgen.

                                          Error received reading address 37100 from id: 1 with error: undefined
                                          
                                          Alex Warkentin 1 Reply Last reply Reply Quote 0
                                          • Alex Warkentin
                                            Alex Warkentin @juggi1962 last edited by

                                            @juggi1962
                                            Modbus hat einige Fehlercodes. Nur einige davon werden von dem Script auch in Klartext übersetzt. Ich weiß auch nicht, ob das Plugin was wir da verwenden, die ganzen Fehlercodes behandeln kann. Vielleicht hast du ja gar keine Verbindungsabbrüche, sondern der Errorcode liegt einfach außerhalb des Arrays der Messages.

                                            Gehe mal zu der Zeile wo die Warnung generiert wird und dort ganz ans Ende und lösche modbuserrormessages und die eckigen Klammern um den errorcode, sodass nicht die oben definierten Messages, sondern der Fehlercode selbst dargestellt wird. Vielleicht kommt da ja ne Meldung, die man besser analysieren kann.

                                            J 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

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

                                            912
                                            Online

                                            31.9k
                                            Users

                                            80.1k
                                            Topics

                                            1.3m
                                            Posts

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