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

  • Default (No Skin)
  • No Skin
Collapse
ioBroker Logo

Community Forum

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

NEWS

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

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

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

Huawei Sun2000 & ioBroker via JS script funktioniert

Scheduled Pinned Locked Moved ioBroker Allgemein
481 Posts 62 Posters 121.7k Views 63 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Chris_B

    @sweatchuck
    Hallo
    Hier mein aktueller Stand des Skripts. Bitte beachten:

    • Das Skript ist noch NICHT fertig. Ich werde in den nächsten Tagen noch weitere Verbesserungen vornehmen.
    • Unter client.connectTCP("192.168.0.0", { port: 502 }); die eigene TCP-IP Adresse des INverters angeben
    • Verwendung des Skripts auf eigene Verantwortung.
      Das Skript erzeugt neu noch zusätzliche Variable unter Solarpower.Derived.XXX. Die Beschreibung der Variable ist meist selbsterklärend.
      Ich werde in den nächsten Tagen und Wochen noch folgendes erweitern:
    1. Am Ende jedes Tages die aktuellen Werte in ein File schreiben, zur Analyse in bspw. Excel.
    2. Den Tagesverbrauch ausgeben (wie im Huawei Portal)
    3. Den Modbus-Trafic verringern (bspw. Nachts)
    4. Mein UI verbessern
      Hier mein aktuelles UI und das Skript.

    c6e56fff-e6e6-4cbd-b19b-017c56317b72-grafik.png

    // From iobroker Forum: "Huawei Sun2000 & ioBroker via JS script funktioniert"
    // https://forum.iobroker.net/topic/53005/huawei-sun2000-iobroker-via-js-script-funktioniert
    //
    
    createState("javascript.0.Solarpower.Derived.BatteryOverview", "",  {read: true, write: true, name: "Battery Overview SOC"});
    createState("javascript.0.Solarpower.Derived.HouseConsumption", "",  {read: true, write: true, name: "Consumption of House", unit: "W"});
    createState("javascript.0.Solarpower.Derived.YieldToday", "",  {read: true, write: true, name: "Yield Today", unit: "kW"});
    createState("javascript.0.Solarpower.Derived.IsBatteryLoading", 0,  {read: true, write: true, name: "Luna 2000 Battery is loading", type: "number"});
    createState("javascript.0.Solarpower.Derived.IsGridExporting", 0,  {read: true, write: true, name: "Exporting Power to Grid", type: "number"});
    createState("javascript.0.Solarpower.Derived.PeakPanelPower", 0,  {read: true, write: true, name: "Peak panel power today"});
    createState("javascript.0.Solarpower.Derived.GridExportSum", 0,  {read: true, write: true, name: "Total export to grid", unit: "kWh"});
    createState("javascript.0.Solarpower.Derived.GridImportSum", 0,  {read: true, write: true, name: "Total import from grid", unit: "kWh"});
    createState("javascript.0.Solarpower.Derived.GridExportToday", 0,  {read: true, write: true, name: "Export to grid today", unit: "kWh"});
    createState("javascript.0.Solarpower.Derived.GridImportToday", 0,  {read: true, write: true, name: "Import from grid today", unit: "kWh"});
    
    
    var ModbusRTU = require("modbus-serial");
    var client = new ModbusRTU();
    var testCreateState = 0;
    
    var modbusErrorMessages =
    [   "Unknown error",
        "Illegal function (device does not support this read/write function)",
        "Illegal data address (register not supported by device)",
        "Illegal data value (value cannot be written to this register)",
        "Slave device failure (device reports internal error)",
        "Acknowledge (requested data will be available later)",
        "Slave device busy (retry request again later)"
    ];
    
    // open connection to a tcp line
    client.setTimeout(10000);
    
    // Enter your inverter modbus IP and port here:
    client.connectTCP("192.168.0.0", { port: 502 });
    // Enter the Modbus-IDs of your Sun2000 inverters here (example for two inverters): const ModBusIDs = [16, 1];
    const ModBusIDs = [1];
    // On which Modbus-ID can we reach the power meter? (via Sun2000!)
    const PowerMeterID = 0;
    // Enter your battery stack setup. 2 dimensional array, e.g. [[3, 2], [3, 0]] means:
    // First inverter has two battery stacks with 3 + 2 battery modules
    // while second inverter has only one battery stack with 3 battery modules
    const BatteryUnits = [[3, 0]];
    
    // These register spaces need to be read:
    const RegisterSpacesToReadContinuously = [[30000, 81], [37100, 114], [32000, 116], [37000, 68],  [37700, 100], [37800, 100], [38200, 100], [38300, 100], [38400, 100], [35300, 40]];
    var RegisterSpacesToReadContinuouslyPtr = 0;
    
    var GlobalDataBuffer = new Array(2);
    for ( var i=0; i < ModBusIDs.length; i++)
    {
        GlobalDataBuffer[i] = new Array(50000); // not optimized....
    }
    
    
    // Some helper functions:
    
    function readUnsignedInt16(array)
    {   return array[0];
    }
    
    function readUnsignedInt32(array)
    {   return array[0] * 256 * 256 + array[1];
    }
    
    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)
    {   return readUnsignedInt16(dataarray.slice(index, index+1));
    }
    
    function getU32(dataarray, index)
    {   return readUnsignedInt32(dataarray.slice(index, index+2));
    }
    
    function getI16(dataarray, index)
    {   return readSignedInt16(dataarray.slice(index, index+1));
    }
    
    function getI32(dataarray, index)
    {   return readSignedInt32(dataarray.slice(index, index+2));
    }
    
    function getString(dataarray, index, length)
    {   var shortarray = dataarray.slice(index, index+length);
        var bytearray = [];
        for (var i = 0; i < length; i++)
        {   bytearray.push(dataarray[index+i] >> 8);
            bytearray.push(dataarray[index+i] & 0xff);
        }       
        var value =  String.fromCharCode.apply(null, bytearray);    
        return value;
    }
    
    function getZeroTerminatedString(dataarray, index, length)
    {   var shortarray = dataarray.slice(index, index+length);
        var bytearray = [];
        for(var i = 0; i < length; i++)
        {   bytearray.push(dataarray[index+i] >> 8);
            bytearray.push(dataarray[index+i] & 0xff);
        }       
        var value =  String.fromCharCode.apply(null, bytearray);    
        var value2 = new String(value).trim();
        return value2;
    }
    
    function forcesetState(objectname, value, options)
    //------------------------------------------------
    // perform createState() only if variable does not yet exist, and perform the check via existsState() only once for each processing round
    {   if (testCreateState == 0)
        {   if (!existsState("javascript.0." + objectname)) { createState(objectname, value, options); }
            else                                            { setState(objectname, value); testCreateState = 1; }
        } else
        {   setState(objectname, value);
        }
    }  
    
    
    // Functions to map registers into ioBreaker objects
    
    function ProcessOptimizers(id)
    //----------------------------
    {
        forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerTotalNumber",     getU16(GlobalDataBuffer[id-1], 37200), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerOnlineNumber",    getU16(GlobalDataBuffer[id-1], 37201), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".OptimizerFeatureData",     getU16(GlobalDataBuffer[id-1], 37202), {name: "", unit: ""});
    }
    
    function ProcessInverterPowerAdjustments(id)
    //------------------------------------------
    {
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementMode",     getU16(GlobalDataBuffer[id-1], 35300), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementValue",    getU32(GlobalDataBuffer[id-1], 35301), {name: "", unit: ""}); // Note: This might be an error in the manual. It says register 35302 with quantity 2, but on 35303 is already the next value.
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ActiveAdjustementCommand",  getU16(GlobalDataBuffer[id-1], 35303), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementMode",   getU16(GlobalDataBuffer[id-1], 35304), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementValue",  getU32(GlobalDataBuffer[id-1], 35305), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.ReactiveAdjustementCommand",getU16(GlobalDataBuffer[id-1], 35307), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ActiveAdjustement.PowerMeterActivePower",     getI32(GlobalDataBuffer[id-1], 35313), {name: "", unit: ""});
    }
    
    function ProcessBattery(id)
    //-------------------------
    {
        // Battery registers 1-15 (Stack 1 related)
        if ( BatteryUnits[id-1][0] > 0)
        {
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RunningStatus",               getU16(GlobalDataBuffer[id-1], 37000), {name: "", unit: ""});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.ChargeAndDischargePower",     getI32(GlobalDataBuffer[id-1], 37001), {name: "Charge and Discharge Power", unit: "W"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BusVoltage",                  getU16(GlobalDataBuffer[id-1], 37003) / 10, {name: "Busvoltage", unit: "V"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BatterySOC",                  getU16(GlobalDataBuffer[id-1], 37004) / 10, {name: "Battery SOC", unit: "%"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.WorkingMode",                 getU16(GlobalDataBuffer[id-1], 37006), {name: "Working Mode", unit: ""});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RatedChargePower",            getU32(GlobalDataBuffer[id-1], 37007), {name: "", unit: "W"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RatedDischargePower",         getU32(GlobalDataBuffer[id-1], 37009), {name: "", unit: "W"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.FaultID",                     getU16(GlobalDataBuffer[id-1], 37014), {name: "", unit: ""});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayChargeCapacity",    getU32(GlobalDataBuffer[id-1], 37015) / 100, {name: "", unit: "kWh"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37017) / 100, {name: "", unit: "kWh"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BusCurrent",                  getI16(GlobalDataBuffer[id-1], 37021) / 10, {name: "Buscurrent", unit: "A"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BatteryTemperature",          getI16(GlobalDataBuffer[id-1], 37022) / 10, {name: "Battery Temperatue", unit: "°C"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.RemainingChargeDischargeTime",getU16(GlobalDataBuffer[id-1], 37025), {name: "", unit: "mins"});
            //forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.DCDCversion",                 getZeroTerminatedString(GlobalDataBuffer[id-1], 37026, 10), {name: "", unit: ""});
            //forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.BMSversion",                  getZeroTerminatedString(GlobalDataBuffer[id-1], 37036, 10), {name: "", unit: ""});
        }
        // Battery registers 16+17 (Storage-related)
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.MaximumChargePower",                     getU32(GlobalDataBuffer[id-1], 37046), {name: "", unit: "W"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.MaximumDischargePower",                  getU32(GlobalDataBuffer[id-1], 37048), {name: "", unit: "W"});
    
        // Battery register 18-20 (Stack 1 related)
        if (BatteryUnits[id-1][0] > 0)
        {
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.SN",                          getZeroTerminatedString(GlobalDataBuffer[id-1], 37052, 10), {name: "Serialnumber", unit: ""});       
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.TotalCharge",                 getU32(GlobalDataBuffer[id-1], 37066) / 100, {name: "", unit: "kWh"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.TotalDischarge",              getU32(GlobalDataBuffer[id-1], 37068) / 100, {name: "", unit: "kWh"});
        }
        // Battery register 21-31 (Stack 2 related)
        if ( BatteryUnits[id-1][1] > 0)
        {
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.SN",                          getZeroTerminatedString(GlobalDataBuffer[id-1], 37700, 10), {name: "Serialnumber", unit: ""});        
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BatterySOC",                  getU16(GlobalDataBuffer[id-1], 37738) / 10, {name: "", unit: "%"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.RunningStatus",               getU16(GlobalDataBuffer[id-1], 37741), {name: "", unit: ""});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.ChargeAndDischargePower",     getI32(GlobalDataBuffer[id-1], 37743), {name: "", unit: "W"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayChargeCapacity",    getU32(GlobalDataBuffer[id-1], 37746) / 100, {name: "", unit: "kWh"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37748) / 100, {name: "", unit: "kWh"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BusVoltage",                  getU16(GlobalDataBuffer[id-1], 37750) / 10, {name: "", unit: "V"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BusCurrent",                  getI16(GlobalDataBuffer[id-1], 37751) / 10, {name: "", unit: "A"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.BatteryTemperature",          getI16(GlobalDataBuffer[id-1], 37752) / 10, {name: "", unit: "°C"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.TotalCharge",                 getU32(GlobalDataBuffer[id-1], 37753) / 100, {name: "", unit: "kWh"});
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.TotalDischarge",              getU32(GlobalDataBuffer[id-1], 37755) / 100, {name: "", unit: "kWh"});
        }
        // Battery register 32-41 (Storage related)
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.RatedCapacity", getU32(GlobalDataBuffer[id-1], 37758) / 1, {name: "", unit: "Wh"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.SOC", getU16(GlobalDataBuffer[id-1], 37760) / 10, {name: "", unit: "%"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.RunningStatus", getU16(GlobalDataBuffer[id-1], 37762) / 1, {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.BusVoltage", getU16(GlobalDataBuffer[id-1], 37763) / 10, {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.BusCurrent", getI16(GlobalDataBuffer[id-1], 37764) / 10, {name: "", unit: "A"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 37765) / 1, {name: "", unit: "W"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.TotalCharge", getU32(GlobalDataBuffer[id-1], 37780) / 100, {name: "", unit: "kWh"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.TotalDischarge", getU32(GlobalDataBuffer[id-1], 37782) / 100, {name: "", unit: "kWh"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.CurrentDayChargeCapacity", getU32(GlobalDataBuffer[id-1], 37784) / 100, {name: "", unit: "kWh"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Battery.CurrentDayDischargeCapacity", getU32(GlobalDataBuffer[id-1], 37786) / 100, {name: "Current DayDiscarge ", unit: "kWh"});
    
        // Battery registers 42+43 (Battery stack related)   
        if ( BatteryUnits[id-1][1] > 0)
        {
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.2.SoftwareVersion",    getZeroTerminatedString(GlobalDataBuffer[id-1], 37814, 8), {name: "Softwareversion", unit: ""});
        }
        
        if ( BatteryUnits[id-1][0] > 0)
        {
            forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack.1.SoftwareVersion",    getZeroTerminatedString(GlobalDataBuffer[id-1], 37799, 8), {name: "Softwareversion", unit: ""});
        }
    
        // Registers 44 to 98: (Battery pack related)
        for(var i = 1; i <= 2; i++)
        {        
            if(BatteryUnits[id-1][i-1] >= 0)
            {            
                for(var j = 1; j <= BatteryUnits[id-1][i-1]; j++)
                {
                    //[[38200, 38242, 38284] [38326, 38368, 38410]]; (+42 for each battery pack, +126 for each stack)
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".SN",                getZeroTerminatedString(GlobalDataBuffer[id-1], 38200+(i-1)*126+(j-1)*42, 6), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".FirmwareVersion",   getZeroTerminatedString(GlobalDataBuffer[id-1], 38210+(i-1)*126+(j-1)*42, 8), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".WorkingStatus",     getU16(GlobalDataBuffer[id-1], 38228+(i-1)*126+(j-1)*42), {name: "", unit: ""});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".BatterySOC",        getU16(GlobalDataBuffer[id-1], 38229+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "%"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".ChargeAndDischargePower", getI32(GlobalDataBuffer[id-1], 38233+(i-1)*126+(j-1)*42) / 1000, {name: "", unit: "kW"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Voltage",           getU16(GlobalDataBuffer[id-1], 38235+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "V"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".Current",           getI16(GlobalDataBuffer[id-1], 38236+(i-1)*126+(j-1)*42) / 10, {name: "", unit: "A"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".TotalCharge",       getU32(GlobalDataBuffer[id-1], 38238+(i-1)*126+(j-1)*42) / 100, {name: "", unit: "kWh"});
                    forcesetState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".TotalDischarge",    getU32(GlobalDataBuffer[id-1], 38240+(i-1)*126+(j-1)*42) / 100, {name: "", unit: "kWh"});
    
                    // [[38452, 38454, 38456][38458, 38460, 38462]] ( +2 for each pack, +6 for each stack)
                    createState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".MaxTemperature", getI16(GlobalDataBuffer[id-1], 38452+(i-1)*6+(j-1)*2) / 10, {name: "", unit: "°C"});
                    createState("Solarpower.Huawei.Inverter." + id + ".Batterystack." + i + ".Battery" + j + ".MinTemperature", getI16(GlobalDataBuffer[id-1], 38453+(i-1)*6+(j-1)*2) / 10, {name: "", unit: "°C"});
                }
            }        
        }
    
        // Battery registers 110-141 are not supported by this script yet!
    }
    
    
    function ProcessPowerMeterStatus()
    //--------------------------------
    {       
        forcesetState("Solarpower.Huawei.Meter.Status",                   getU16(GlobalDataBuffer[PowerMeterID], 37100), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Meter.VoltageL1",                getI32(GlobalDataBuffer[PowerMeterID], 37101)  / 10, {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Meter.VoltageL2",                getI32(GlobalDataBuffer[PowerMeterID], 37103)  / 10, {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Meter.VoltageL3",                getI32(GlobalDataBuffer[PowerMeterID], 37105)  / 10, {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Meter.CurrentL1",                getI32(GlobalDataBuffer[PowerMeterID], 37107)  / 100, {name: "", unit: "A"});
        forcesetState("Solarpower.Huawei.Meter.CurrentL2",                getI32(GlobalDataBuffer[PowerMeterID], 37109)  / 100, {name: "", unit: "A"});
        forcesetState("Solarpower.Huawei.Meter.CurrentL3",                getI32(GlobalDataBuffer[PowerMeterID], 37111) / 100, {name: "", unit: "A"});
        forcesetState("Solarpower.Huawei.Meter.ActivePower",              getI32(GlobalDataBuffer[PowerMeterID], 37113) / 1, {name: "", unit: "W"});
        forcesetState("Solarpower.Huawei.Meter.ReactivePower",            getI32(GlobalDataBuffer[PowerMeterID], 37115) / 1, {name: "", unit: "Var"});
        forcesetState("Solarpower.Huawei.Meter.PowerFactor",              getI16(GlobalDataBuffer[PowerMeterID], 37117) / 1000, {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Meter.GridFrequency",            getI16(GlobalDataBuffer[PowerMeterID], 37118) / 100, {name: "", unit: "Hz"});
        forcesetState("Solarpower.Huawei.Meter.PositiveActiveEnergy",     getI32(GlobalDataBuffer[PowerMeterID], 37119) / 100, {name: "", unit: "kWh"});
        forcesetState("Solarpower.Huawei.Meter.ReverseActiveEnergy",      getI32(GlobalDataBuffer[PowerMeterID], 37121) / 100, {name: "", unit: "kWh"});
        forcesetState("Solarpower.Huawei.Meter.AccumulatedReactivePower", getI32(GlobalDataBuffer[PowerMeterID], 37123) / 100, {name: "", unit: "kVarh"});
        //forcesetState("Solarpower.Huawei.Meter.MeterType",                getU16(GlobalDataBuffer[PowerMeterID], 37125), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Meter.VoltageL1-L2",             getI32(GlobalDataBuffer[PowerMeterID], 37126) / 10, {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Meter.VoltageL2-L3",             getI32(GlobalDataBuffer[PowerMeterID], 37128) / 10, {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Meter.VoltageL3-L1",             getI32(GlobalDataBuffer[PowerMeterID], 37130) / 10, {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Meter.ActivePowerL1",            getI32(GlobalDataBuffer[PowerMeterID], 37132) / 1, {name: "", unit: "W"});
        forcesetState("Solarpower.Huawei.Meter.ActivePowerL2",            getI32(GlobalDataBuffer[PowerMeterID], 37134) / 1, {name: "", unit: "W"});
        forcesetState("Solarpower.Huawei.Meter.ActivePowerL3",            getI32(GlobalDataBuffer[PowerMeterID], 37136) / 1, {name: "", unit: "W"});
        //forcesetState("Solarpower.Huawei.Meter.MeterModel",               getU16(GlobalDataBuffer[PowerMeterID], 37138), {name: "", unit: ""});
    }
    
    function ProcessInverterStatus(id)
    //--------------------------------
    {
        forcesetState("Solarpower.Huawei.Inverter." + id + ".State1", getU16(GlobalDataBuffer[id-1], 32000), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".State2", getU16(GlobalDataBuffer[id-1], 32001), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".State3", getU16(GlobalDataBuffer[id-1], 32002), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Alarm1", getU16(GlobalDataBuffer[id-1], 32008), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Alarm2", getU16(GlobalDataBuffer[id-1], 32009), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Alarm3", getU16(GlobalDataBuffer[id-1], 32010), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".String.1_Voltage",       getI16(GlobalDataBuffer[id-1], 32016) / 10  , {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".String.1_Current",       getI16(GlobalDataBuffer[id-1], 32017) / 100 , {name: "", unit: "A"});
        //forcesetState("Solarpower.Huawei.Inverter." + id + ".String.2_Voltage",       getI16(GlobalDataBuffer[id-1], 32018) / 10  , {name: "", unit: "V"});
        //forcesetState("Solarpower.Huawei.Inverter." + id + ".String.2_Current",       getI16(GlobalDataBuffer[id-1], 32019) / 100 , {name: "", unit: "A"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".InputPower",             getI32(GlobalDataBuffer[id-1], 32064) / 1000, {name: "", unit: "kW"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L1-L2_Voltage",           getU16(GlobalDataBuffer[id-1], 32066) / 10  , {name: "", unit: "V"});      
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L2-L3_Voltage",           getU16(GlobalDataBuffer[id-1], 32067) / 10  , {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L3-L1_Voltage",           getU16(GlobalDataBuffer[id-1], 32068) / 10  , {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L1_Voltage",            getU16(GlobalDataBuffer[id-1], 32069) / 10  , {name: "", unit: "V"});                              
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L2_Voltage",            getU16(GlobalDataBuffer[id-1], 32070) / 10  , {name: "", unit: "V"});                                                  
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L3_Voltage",            getU16(GlobalDataBuffer[id-1], 32071) / 10  , {name: "", unit: "V"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L1_Current",         getI32(GlobalDataBuffer[id-1], 32072) / 1000, {name: "", unit: "A"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L2_Current",         getI32(GlobalDataBuffer[id-1], 32074) / 1000, {name: "", unit: "A"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Grid.L3_Current",         getI32(GlobalDataBuffer[id-1], 32076) / 1000, {name: "", unit: "A"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".PeakActivePowerDay",     getI32(GlobalDataBuffer[id-1], 32078) / 1000, {name: "", unit: "kW"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ActivePower",            getI32(GlobalDataBuffer[id-1], 32080) / 1000, {name: "", unit: "kW"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ReactivePower",          getI32(GlobalDataBuffer[id-1], 32082) / 1000, {name: "", unit: "kVar"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".PowerFactor",            getI16(GlobalDataBuffer[id-1], 32084) / 1000, {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".GridFrequency",          getU16(GlobalDataBuffer[id-1], 32085) / 100 , {name: "", unit: "Hz"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Efficiency",             getU16(GlobalDataBuffer[id-1], 32086) / 100 , {name: "", unit: "%"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".InternalTemperature",    getI16(GlobalDataBuffer[id-1], 32087) / 10  , {name: "", unit: "°C"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".InsulationResistance",   getU16(GlobalDataBuffer[id-1], 32088) / 1000, {name: "", unit: "MOhm"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".DeviceStatus",              getU16(GlobalDataBuffer[id-1], 32089), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".FaultCode",                 getU16(GlobalDataBuffer[id-1], 32090), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".StartupTime",               getU16(GlobalDataBuffer[id-1], 32091), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ShutdownTime",              getU16(GlobalDataBuffer[id-1], 32093), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".AccumulatedEnergyYield",    getU32(GlobalDataBuffer[id-1], 32106) / 100, {name: "", unit: "kWh"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".DailyEnergyYield",          getU32(GlobalDataBuffer[id-1], 32114) / 100, {name: "", unit: "kWh"});
    }
    
    
    function ProcessDeviceInfo(id)
    //----------------------------
    {      
        // Note: Manual says its quantitiy is 15, but that is the number (+1) of 8bit characters
        forcesetState("Solarpower.Huawei.Inverter." + id + ".Model",  getZeroTerminatedString(GlobalDataBuffer[id-1], 30000, 8), {name: "", unit: ""}); 
        forcesetState("Solarpower.Huawei.Inverter." + id + ".SN",     getZeroTerminatedString(GlobalDataBuffer[id-1], 30015, 6), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".PN",     getZeroTerminatedString(GlobalDataBuffer[id-1], 30025, 6), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".ModelID",           getU16(GlobalDataBuffer[id-1], 30070), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".PVStrings",         getU16(GlobalDataBuffer[id-1], 30071), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".MPPTrackers",       getU16(GlobalDataBuffer[id-1], 30072), {name: "", unit: ""});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxRatedPower",     getU32(GlobalDataBuffer[id-1], 30073) / 1000, {name: "", unit: "kW"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxActivePower",    getU32(GlobalDataBuffer[id-1], 30075) / 1000, {name: "", unit: "kW"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxApparentPower",  getU32(GlobalDataBuffer[id-1], 30077) / 1000, {name: "", unit: "kVA"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxReactivePowerToGrid",        getI32(GlobalDataBuffer[id-1], 30079) / 1000, {name: "", unit: "kVAr"});
        forcesetState("Solarpower.Huawei.Inverter." + id + ".MaxReactivePowerFromGrid",      getI32(GlobalDataBuffer[id-1], 30081) / 1000, {name: "", unit: "kVAr"});
    }
    
    
    function readRegisterSpace(id, address, length)
    //---------------------------------------------
    {
        client.setID(ModBusIDs[id-1]);
        client.readHoldingRegisters(address, length, function(err, data)
        {   
            if (err)
            {   console.warn("Error received reading address " + address + " from id: " + ModBusIDs[id-1] + " with error: " + modbusErrorMessages[err.modbusCode]);            
            }
            else
            {   console.debug("Read data from id/address " + ModBusIDs[id-1] + "/" + address + "\nData is: " + data.data);
                for (var i = 0; i < length; i++) GlobalDataBuffer[id-1][address+i] = data.data[i];
            }
        });
    }
    
    
    function ProcessData()
    //--------------------
    {
        console.debug("Processing new data...");   // this was originally .log
        for ( var i = 1; i <= ModBusIDs.length; i++)
        {
            ProcessDeviceInfo(i);
            ProcessInverterStatus(i);
            ProcessBattery(i);
            //ProcessInverterPowerAdjustments(i);
            ProcessOptimizers(i); 
        }    
        ProcessPowerMeterStatus();
    
        // get SOC of all batteries and combine to one string
        var BatOverview = getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery1.BatterySOC").val + "%, " +
            getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery2.BatterySOC").val + "%, " +
            getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery3.BatterySOC").val + "%";
        setState("javascript.0.Solarpower.Derived.BatteryOverview", BatOverview);
    
        // determine peak panel power
        var PanelPower = getState("javascript.0.Solarpower.Huawei.Inverter.1.InputPower").val;
        var PanelMax = getState("javascript.0.Solarpower.Derived.PeakPanelPower").val;
        if (PanelPower > PanelMax) setState("javascript.0.Solarpower.Derived.PeakPanelPower", PanelPower);
        
        // determine power used by house
        setState("javascript.0.Solarpower.Derived.HouseConsumption", getState("javascript.0.Solarpower.Huawei.Inverter.1.ActivePower").val * 1000 -
            getState("javascript.0.Solarpower.Huawei.Meter.ActivePower").val);
    
        // determine yield today
        setState("javascript.0.Solarpower.Derived.YieldToday", getState("javascript.0.Solarpower.Huawei.Inverter.1.DailyEnergyYield").val +
            getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.CurrentDayChargeCapacity").val -
            getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.CurrentDayDischargeCapacity").val)
    
        // determine if battery is loading
        setState("javascript.0.Solarpower.Derived.IsBatteryLoading", getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.ChargeAndDischargePower").val > 0 ? 0 : 1);
    
        // determine if power is imported or exported
        setState("javascript.0.Solarpower.Derived.IsGridExporting", getState("javascript.0.Solarpower.Huawei.Meter.ActivePower").val > 0 ? 1 : 0);
    
        // compute export and import today
        setState("javascript.0.Solarpower.Derived.GridExportToday", getState("javascript.0.Solarpower.Huawei.Meter.PositiveActiveEnergy").val - getState("javascript.0.Solarpower.Derived.GridExportSum").val);
        setState("javascript.0.Solarpower.Derived.GridImportToday", getState("javascript.0.Solarpower.Huawei.Meter.ReverseActiveEnergy").val - getState("javascript.0.Solarpower.Derived.GridImportSum").val);
        
        console.debug("Processing done!");  // this was originally .log
    }
    
    
    var triggerprocessing = 0; 
    var currentinverter = 1;
    
    setInterval(function()
    // -------------------
    // This is the main function triggering a  read via modbus-tcp every 2 seconds - changed to 5 seconds
    // Processing of data is triggered as soon as one complete set of registers is copied
    // with 5 seconds, new values are displyed every 50 seconds
    {
        if (triggerprocessing == 1)
        {
            triggerprocessing = 0;
            ProcessData();
            testCreateState = 0;       
        }      
       
        // this was originally also a .log
        console.debug("Triggering read of inverter " + currentinverter + " at address " +
            RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0] +
            " with length " +  RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]);
        
        readRegisterSpace(currentinverter, RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0], RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]); 
        RegisterSpacesToReadContinuouslyPtr++;               
        if (RegisterSpacesToReadContinuouslyPtr >= RegisterSpacesToReadContinuously.length)
        {
            RegisterSpacesToReadContinuouslyPtr = 0;
            currentinverter++
            if (currentinverter > ModBusIDs.length)
            {
                currentinverter = 1;  
                triggerprocessing = 1;                    
            }
        }     
    }, 5000);
    
    
    // one minute before midnight - perform housekeeping actions
    schedule("59 23 * * *", function ()
    {   
        // reset peak power for next day
        setState("javascript.0.Solarpower.Derived.PeakPanelPower", 0);
        // copy current export/import kWh - used to compute daily import/export in kWh
        setState("javascript.0.Solarpower.Derived.GridExportSum", getState("javascript.0.Solarpower.Huawei.Meter.PositiveActiveEnergy").val);
        setState("javascript.0.Solarpower.Derived.GridImportSum", getState("javascript.0.Solarpower.Huawei.Meter.ReverseActiveEnergy").val);
    });
    
    
    S Offline
    S Offline
    Sweatchuck
    wrote on last edited by
    #121

    @chris_b

    Vielen herzlichen Dank.

    Deine Updates/Verbesserungen würde ich natürlich gerne auch bei mir integrieren.

    Wenn ich bei der Entwicklung/Weiterentwicklung unterstützen kann (Tester etc.), lass es mich wissen!

    Gruß

    C 1 Reply Last reply
    0
    • A Offline
      A Offline
      anno171986
      wrote on last edited by anno171986
      #122

      @Chris_B Vielen Dank für dein Skript. Ich habe die vorletzte Vdersion und mit der Ausnahme der Datenpunkterzeugung läuft es auch gut.

      Was mich ein bisschen ärgert ist, das Huawei anscheinend nicht alle Werte hier per API bereitstellt die man über die App sieht. Mich interessiert z.B. der Gesamtstromverbrauch am Tag. Kann man den aus den vorliegenden Werten berechnen, bin da noch nicht fündig geworden.

      VG

      C 1 Reply Last reply
      0
      • S Sweatchuck

        @chris_b

        Vielen herzlichen Dank.

        Deine Updates/Verbesserungen würde ich natürlich gerne auch bei mir integrieren.

        Wenn ich bei der Entwicklung/Weiterentwicklung unterstützen kann (Tester etc.), lass es mich wissen!

        Gruß

        C Offline
        C Offline
        Chris_B
        wrote on last edited by
        #123

        @sweatchuck
        Mach ich gerne. Und Feedback, Testen sind sehr willkommen. Gerne würde ich mich auch in Sachen Sun2000 / Luna 2000 austauschen. Ich habe da noch einige Fragen. Ich melde mich am Wochenende. Bin gerade ziemlich mit Arbeit zu...
        Danke und Gruss

        1 Reply Last reply
        0
        • A anno171986

          @Chris_B Vielen Dank für dein Skript. Ich habe die vorletzte Vdersion und mit der Ausnahme der Datenpunkterzeugung läuft es auch gut.

          Was mich ein bisschen ärgert ist, das Huawei anscheinend nicht alle Werte hier per API bereitstellt die man über die App sieht. Mich interessiert z.B. der Gesamtstromverbrauch am Tag. Kann man den aus den vorliegenden Werten berechnen, bin da noch nicht fündig geworden.

          VG

          C Offline
          C Offline
          Chris_B
          wrote on last edited by
          #124

          @anno171986 Was meinst Du genau mit dem Problem der Datenpunkterzeugung?
          Am besten Skript stoppen, Alle Datenpunkte löschen und Skript wieder neu starten.
          Noch eine Bemerkung: Gewisse Datenpunkte werden erst 'sinnvoll' wenn einmal Mitternacht durch ist, da Differenzen zum Vortag benötigt werden...
          Gruss

          A 1 Reply Last reply
          0
          • C Chris_B

            @anno171986 Was meinst Du genau mit dem Problem der Datenpunkterzeugung?
            Am besten Skript stoppen, Alle Datenpunkte löschen und Skript wieder neu starten.
            Noch eine Bemerkung: Gewisse Datenpunkte werden erst 'sinnvoll' wenn einmal Mitternacht durch ist, da Differenzen zum Vortag benötigt werden...
            Gruss

            A Offline
            A Offline
            anno171986
            wrote on last edited by anno171986
            #125

            @chris_b
            Vorweg: ich habe mein Skript noch nicht mit deinem neuen Stand vom 05.06.2023 aktualisiert.
            Bei mir waren die Werte immer nur einmal aktualisiert worden, n achdem ich die Dtaenpunkte gelöscht hatte. Dann wurden sie per Skript einmaöl neu angelegt aber danach nicht mehr aktualisiert. Habe jetzt Teile ausgeklammert, damit funktioniert es:

            function forcesetState(objectname, value, options)
            //------------------------------------------------
            // perform createState() only if variable does not yet exist, and perform the check via existsState() only once for each processing round
            {  
                /* if (testCreateState == 0)
                {   if (!existsState(Folder + objectname)) { createState(objectname, value, options); }
                    else                                            { setState(objectname, value); testCreateState = 1; }
                } else
                {   setState(objectname, value);
                }
                */
                setState(objectname, value);
            }  
            

            Wieviel kwh du verbraucht hast, das kannst du auch nicht auslesen oder berechnen, richtig?

            C 1 Reply Last reply
            0
            • A anno171986

              @chris_b
              Vorweg: ich habe mein Skript noch nicht mit deinem neuen Stand vom 05.06.2023 aktualisiert.
              Bei mir waren die Werte immer nur einmal aktualisiert worden, n achdem ich die Dtaenpunkte gelöscht hatte. Dann wurden sie per Skript einmaöl neu angelegt aber danach nicht mehr aktualisiert. Habe jetzt Teile ausgeklammert, damit funktioniert es:

              function forcesetState(objectname, value, options)
              //------------------------------------------------
              // perform createState() only if variable does not yet exist, and perform the check via existsState() only once for each processing round
              {  
                  /* if (testCreateState == 0)
                  {   if (!existsState(Folder + objectname)) { createState(objectname, value, options); }
                      else                                            { setState(objectname, value); testCreateState = 1; }
                  } else
                  {   setState(objectname, value);
                  }
                  */
                  setState(objectname, value);
              }  
              

              Wieviel kwh du verbraucht hast, das kannst du auch nicht auslesen oder berechnen, richtig?

              C Offline
              C Offline
              Chris_B
              wrote on last edited by
              #126

              @anno171986 Ganz kurz: Bitte das neuste Skript nehmen. Das mit den Datenpunkten ist ein Problem des ursprünglichen Skripts (nicht von mir). Nochmals alle Datenpunkte löschen und das neuste Skript nehmen.
              Den Verbrauch an einem Tag kann man rechnen. Das habe ich noch nicht gemacht, ist nicht sehr kompliziert, kommt vermutlich am Wochenende. Bitte etwas Geduld…
              Ich möchte auch noch eine bessere Doku machen, damit es verständlich ist, was das Skript macht und kann. Ich möchte alle sinnvollen Werte der Huawei App in iobroker darstellen können…
              Gruss

              R 1 Reply Last reply
              0
              • C Chris_B

                @anno171986 Ganz kurz: Bitte das neuste Skript nehmen. Das mit den Datenpunkten ist ein Problem des ursprünglichen Skripts (nicht von mir). Nochmals alle Datenpunkte löschen und das neuste Skript nehmen.
                Den Verbrauch an einem Tag kann man rechnen. Das habe ich noch nicht gemacht, ist nicht sehr kompliziert, kommt vermutlich am Wochenende. Bitte etwas Geduld…
                Ich möchte auch noch eine bessere Doku machen, damit es verständlich ist, was das Skript macht und kann. Ich möchte alle sinnvollen Werte der Huawei App in iobroker darstellen können…
                Gruss

                R Offline
                R Offline
                road_runner31
                wrote on last edited by road_runner31
                #127

                @chris_b Hi, ich habe diesen Thread gerade gefunden und das Script bei mir installiert. Wenn ich es starte, erscheinen nach einigen Sekunden Warnungen, die dann zyklisch wiederholt werden
                3806a15e-8c37-4ee2-8752-6267e944d054-image.png
                In den Objekten erscheinen Werte, die zunächst grün sind, dann rot werden. Auch scheinen die Werte falsch formatiert zu sein?
                0e0fb81d-eb37-40fc-b080-4965b245fb82-image.png
                Hab ich irgendwo einen Fehler in der Konfiguration gemacht?
                0d753b80-cda5-4b25-8bda-9f9269fc984c-image.png
                Der Battery Overview scheint ja auch nicht zu klappen.
                Habe eine SUN2000 mit 10kWh Speicher in 2 Modulen.. Ein Tipp wäre super!
                Und: VIELEN DANK für die Arbeit, die da drin steckt! :)

                C exelE 2 Replies Last reply
                0
                • R road_runner31

                  @chris_b Hi, ich habe diesen Thread gerade gefunden und das Script bei mir installiert. Wenn ich es starte, erscheinen nach einigen Sekunden Warnungen, die dann zyklisch wiederholt werden
                  3806a15e-8c37-4ee2-8752-6267e944d054-image.png
                  In den Objekten erscheinen Werte, die zunächst grün sind, dann rot werden. Auch scheinen die Werte falsch formatiert zu sein?
                  0e0fb81d-eb37-40fc-b080-4965b245fb82-image.png
                  Hab ich irgendwo einen Fehler in der Konfiguration gemacht?
                  0d753b80-cda5-4b25-8bda-9f9269fc984c-image.png
                  Der Battery Overview scheint ja auch nicht zu klappen.
                  Habe eine SUN2000 mit 10kWh Speicher in 2 Modulen.. Ein Tipp wäre super!
                  Und: VIELEN DANK für die Arbeit, die da drin steckt! :)

                  C Offline
                  C Offline
                  Chris_B
                  wrote on last edited by
                  #128

                  @road_runner31 Hallo. Kurz ein paar Hinweise. Das ursprüngliche Skript ist nicht von mir, siehe ganz oben in diesem thread. Ich habe das Skript abgeändert, Fehler korrigiert und bin am erweitern. Was mir einfällt:

                  1. Im Javascript Adapter muss (!!) Modbus-Serial eingetragen sein:
                    2ff9b482-b420-4f49-ae75-ac99dff72798-grafik.png
                  2. Prüfe Deine IP Adresse.
                  3. Die PowerMeterID musst Du ausprobieren, scheint aber meist 0 zu sein.
                  4. Du schreibst, dass Deine Luna2000 2 Module hat, dann solltest Du auch entsprechen BatteryUnits = [[2, 0]]; schreiben.
                  5. Einige Werte unter 'Derived' sind erst nach dem erstamligen Überschreiten von Mitternacht sinnvoll gefüllt.

                  Mehr fällt mir gerade nicht ein. Gruss

                  R 1 Reply Last reply
                  0
                  • C Chris_B

                    @road_runner31 Hallo. Kurz ein paar Hinweise. Das ursprüngliche Skript ist nicht von mir, siehe ganz oben in diesem thread. Ich habe das Skript abgeändert, Fehler korrigiert und bin am erweitern. Was mir einfällt:

                    1. Im Javascript Adapter muss (!!) Modbus-Serial eingetragen sein:
                      2ff9b482-b420-4f49-ae75-ac99dff72798-grafik.png
                    2. Prüfe Deine IP Adresse.
                    3. Die PowerMeterID musst Du ausprobieren, scheint aber meist 0 zu sein.
                    4. Du schreibst, dass Deine Luna2000 2 Module hat, dann solltest Du auch entsprechen BatteryUnits = [[2, 0]]; schreiben.
                    5. Einige Werte unter 'Derived' sind erst nach dem erstamligen Überschreiten von Mitternacht sinnvoll gefüllt.

                    Mehr fällt mir gerade nicht ein. Gruss

                    R Offline
                    R Offline
                    road_runner31
                    wrote on last edited by
                    #129

                    @chris_b Hallo, danke für die Antworten. Die Anzahl der Module hab ich schon korrigiert. Die IP-Adresse stimmt, es sind ja auch ein paar Werte korrekt (bspw. das Modell). "modbus-serial" ist auch eingebunden.
                    Ich lasse das Script jetzt mal laufen, trotz Fehlern, mal schauen was morgen drinsteht..
                    Viele Grüße!

                    C 1 Reply Last reply
                    0
                    • R road_runner31

                      @chris_b Hallo, danke für die Antworten. Die Anzahl der Module hab ich schon korrigiert. Die IP-Adresse stimmt, es sind ja auch ein paar Werte korrekt (bspw. das Modell). "modbus-serial" ist auch eingebunden.
                      Ich lasse das Script jetzt mal laufen, trotz Fehlern, mal schauen was morgen drinsteht..
                      Viele Grüße!

                      C Offline
                      C Offline
                      Chris_B
                      wrote on last edited by
                      #130

                      @road_runner31 Ich glaube aber, dass Du noch ein anderes Problem hast bei Deiner Anlage. Die Sache mit den Werten nach Mitternacht kann das nicht sein, das ergibt nur am ersten Tag für ein paar Werte sinnlose Zahlen, aber keine Fehlermeldungen.
                      Ich glaube Deine Sun2000 ist nicht ansprechbar. Anwortet sie auf ein PING? Das würde ich einmal als nächstes checken. Gruss

                      1 Reply Last reply
                      0
                      • R road_runner31

                        @chris_b Hi, ich habe diesen Thread gerade gefunden und das Script bei mir installiert. Wenn ich es starte, erscheinen nach einigen Sekunden Warnungen, die dann zyklisch wiederholt werden
                        3806a15e-8c37-4ee2-8752-6267e944d054-image.png
                        In den Objekten erscheinen Werte, die zunächst grün sind, dann rot werden. Auch scheinen die Werte falsch formatiert zu sein?
                        0e0fb81d-eb37-40fc-b080-4965b245fb82-image.png
                        Hab ich irgendwo einen Fehler in der Konfiguration gemacht?
                        0d753b80-cda5-4b25-8bda-9f9269fc984c-image.png
                        Der Battery Overview scheint ja auch nicht zu klappen.
                        Habe eine SUN2000 mit 10kWh Speicher in 2 Modulen.. Ein Tipp wäre super!
                        Und: VIELEN DANK für die Arbeit, die da drin steckt! :)

                        exelE Offline
                        exelE Offline
                        exel
                        wrote on last edited by exel
                        #131

                        @road_runner31 Ich kann das Verhalten bestätigen, sieht bei mir genauso aus.

                        C 1 Reply Last reply
                        0
                        • svenomattS Offline
                          svenomattS Offline
                          svenomatt
                          wrote on last edited by svenomatt
                          #132

                          Hallo zusammen,

                          ich versuche auch gerade das Skript zu laufen zubekommen und habe so meine Probleme.

                          Zunächst sind einige Werte kurz in den Objekten zu sehen. Dann verschwinden diese wieder. Die meisten sind aber nicht befüllt.

                          kurz zur Anlage
                          Sun2000-8ktl-m1
                          10 KW speicher
                          Modbus-Serial in javascript ist eingetragen
                          ModBus-TCP ist an.

                          Hier mal die Meldung: (Dies wiederholt sich dann immer wieder.)

                          17.6.2023, 01:18:00.789	[info ]: javascript.0 (240068) Start javascript script.js.1_Huawei_SUN.Skript_1
                          17.6.2023, 01:18:00.802	[info ]: javascript.0 (240068) script.js.1_Huawei_SUN.Skript_1: registered 0 subscriptions, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          17.6.2023, 01:18:55.806	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                          17.6.2023, 01:18:55.806	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                          17.6.2023, 01:19:45.810	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                          17.6.2023, 01:19:45.810	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                          17.6.2023, 01:20:35.828	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                          17.6.2023, 01:20:35.828	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                          17.6.2023, 01:21:25.820	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                          17.6.2023, 01:21:25.820	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                          17.6.2023, 01:22:15.828	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                          17.6.2023, 01:22:15.828	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                          17.6.2023, 01:23:05.830	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                          17.6.2023, 01:23:05.830	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                          17.6.2023, 01:23:17.082	[info ]: javascript.0 (240068) Stop script script.js.1_Huawei_SUN.Skript_1
                          

                          Für Hilfe wäre ich dankbar

                          C 1 Reply Last reply
                          0
                          • svenomattS svenomatt

                            Hallo zusammen,

                            ich versuche auch gerade das Skript zu laufen zubekommen und habe so meine Probleme.

                            Zunächst sind einige Werte kurz in den Objekten zu sehen. Dann verschwinden diese wieder. Die meisten sind aber nicht befüllt.

                            kurz zur Anlage
                            Sun2000-8ktl-m1
                            10 KW speicher
                            Modbus-Serial in javascript ist eingetragen
                            ModBus-TCP ist an.

                            Hier mal die Meldung: (Dies wiederholt sich dann immer wieder.)

                            17.6.2023, 01:18:00.789	[info ]: javascript.0 (240068) Start javascript script.js.1_Huawei_SUN.Skript_1
                            17.6.2023, 01:18:00.802	[info ]: javascript.0 (240068) script.js.1_Huawei_SUN.Skript_1: registered 0 subscriptions, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                            17.6.2023, 01:18:55.806	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                            17.6.2023, 01:18:55.806	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                            17.6.2023, 01:19:45.810	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                            17.6.2023, 01:19:45.810	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                            17.6.2023, 01:20:35.828	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                            17.6.2023, 01:20:35.828	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                            17.6.2023, 01:21:25.820	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                            17.6.2023, 01:21:25.820	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                            17.6.2023, 01:22:15.828	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                            17.6.2023, 01:22:15.828	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                            17.6.2023, 01:23:05.830	[warn ]: javascript.0 (240068)     at ProcessData (script.js.1_Huawei_SUN.Skript_1:371:9)
                            17.6.2023, 01:23:05.830	[warn ]: javascript.0 (240068)     at Object.<anonymous> (script.js.1_Huawei_SUN.Skript_1:414:9)
                            17.6.2023, 01:23:17.082	[info ]: javascript.0 (240068) Stop script script.js.1_Huawei_SUN.Skript_1
                            

                            Für Hilfe wäre ich dankbar

                            C Offline
                            C Offline
                            Chris_B
                            wrote on last edited by
                            #133

                            @svenomatt
                            Laut Deinem Logist der Fehler bei Dir immer in Zeile 371. Das Skript versucht die dritte Batterie anzusprechen, die gibt es bei Dir nicht. Ich habe das Skript so angepasst, dass das jetzt korrekt sein sollte, möchte das aber erst etwas später ins Forum stellen. Bei Dir sollte (Konjunktiv) folgendes das Problem lösen:
                            Das im Skript

                                // get SOC of all batteries and combine to one string
                                var BatOverview = getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery1.BatterySOC").val + "%, " +
                                    getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery2.BatterySOC").val + "%, " +
                                    getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery3.BatterySOC").val + "%";
                                setState("javascript.0.Solarpower.Derived.BatteryOverview", BatOverview);
                            

                            durch das ersetzen:

                                // get SOC of all batteries and combine to one string
                                var BatOverview = getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery1.BatterySOC").val + "%, " +
                                    getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery2.BatterySOC").val + "%";
                                setState("javascript.0.Solarpower.Derived.BatteryOverview", BatOverview);
                            

                            Funktioniert das?
                            Hintergrund: Im skript oben nehmen ich (einfachheitshalber) an, dass es wie bei mir 3 Batteriepacks sind.

                            1 Reply Last reply
                            0
                            • exelE exel

                              @road_runner31 Ich kann das Verhalten bestätigen, sieht bei mir genauso aus.

                              C Offline
                              C Offline
                              Chris_B
                              wrote on last edited by
                              #134

                              @exel @road_runner31
                              Wenn das Skript bei Euch nicht läuft:
                              Antwortet der Wechselrichter auf ein ping wenn ihr die Adresse, wie ihr sie im Skript eingetragen habt, an-pingt? Der SUN2000 Wechselrichter muss auf ping antworten, sonst läuft das Skript sicher nicht.
                              Zweite Frage: Was sind denn die Fehlermeldungen? Was steht im Log von iobroker?

                              svenomattS R 2 Replies Last reply
                              0
                              • C Chris_B

                                @exel @road_runner31
                                Wenn das Skript bei Euch nicht läuft:
                                Antwortet der Wechselrichter auf ein ping wenn ihr die Adresse, wie ihr sie im Skript eingetragen habt, an-pingt? Der SUN2000 Wechselrichter muss auf ping antworten, sonst läuft das Skript sicher nicht.
                                Zweite Frage: Was sind denn die Fehlermeldungen? Was steht im Log von iobroker?

                                svenomattS Offline
                                svenomattS Offline
                                svenomatt
                                wrote on last edited by svenomatt
                                #135

                                @chris_b

                                Das hat geholfen :), Fehlermeldung sind bei mir komplett Weg.

                                
                                
                                    // get SOC of all batteries and combine to one string
                                 var BatOverview = getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery1.BatterySOC").val + "%, " +
                                getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery2.BatterySOC").val + "%";
                                setState("javascript.0.Solarpower.Derived.BatteryOverview", BatOverview);
                                

                                Vielen Dank für deine schnelle Hilfe. Danke

                                Gruß Sven

                                svenomattS 1 Reply Last reply
                                0
                                • C Chris_B

                                  @exel @road_runner31
                                  Wenn das Skript bei Euch nicht läuft:
                                  Antwortet der Wechselrichter auf ein ping wenn ihr die Adresse, wie ihr sie im Skript eingetragen habt, an-pingt? Der SUN2000 Wechselrichter muss auf ping antworten, sonst läuft das Skript sicher nicht.
                                  Zweite Frage: Was sind denn die Fehlermeldungen? Was steht im Log von iobroker?

                                  R Offline
                                  R Offline
                                  road_runner31
                                  wrote on last edited by
                                  #136

                                  @chris_b Hab das Script jetzt auch angepasst. Hier ein Auszug aus dem Log vom iobroker:
                                  84d97a29-5231-4ba8-97be-3e11c3ddb769-grafik.png
                                  Die IP vom Wechselrichter ist korrekt, evcc läuft ja in einem zweiten Container und beschwert sich auch nicht ;)

                                  1 Reply Last reply
                                  0
                                  • B badsnoopy667

                                    @majawe
                                    Hier der Flow für beide Zustände (Charge und Discharge)
                                    flows_read_write_charge_discharge.json
                                    Sobald du eines der beiden Objekte "_SET" änderst (vorher anlegen!), wird das entsprechende Register geschrieben.
                                    Und wie immer bei meinem Flow: Achte auf die Unit-ID. Bei mir ist die 2, bei dir vermutlich nicht! Mein WR war mal defekt.

                                    Hast Du darauf geachtet beim Ändern nicht nur den Namen, sondern wirklich die Adresse zu ändern? Das hab ich schon ein paar mal durcheinander gebracht. Der Name allein hilft nicht, der ist sowieso völlig beliebig.

                                    karte_modbus.png

                                    B Offline
                                    B Offline
                                    besimo
                                    wrote on last edited by
                                    #137

                                    @badsnoopy667

                                    Kennst du auch Adressen für die Spannung (Unit "V") (und evtl. Temp.) der 5kWh Akkupacks ?

                                    Ich würde gerne die Akkugesundheit prüfen und später überwachen.

                                    In Fusionsolar kann ich zum aktuellen Zeitpunkt die Spannung und Temperatur der beiden Akkus sehen. Historische Daten kann ich mir aber nicht anzeigen lassen.
                                    Das würde ich mir gerne in ioBroker als Graph anzeigen lassen.

                                    In" solar-inverter-modbus-interface-definitions-v3.0" habe ich die Adresse nicht gefunden. Aber Kachel hatte ja auch Adressen in seinem javascript, die dort nicht zu finden waren.

                                    R C 2 Replies Last reply
                                    0
                                    • B besimo

                                      @badsnoopy667

                                      Kennst du auch Adressen für die Spannung (Unit "V") (und evtl. Temp.) der 5kWh Akkupacks ?

                                      Ich würde gerne die Akkugesundheit prüfen und später überwachen.

                                      In Fusionsolar kann ich zum aktuellen Zeitpunkt die Spannung und Temperatur der beiden Akkus sehen. Historische Daten kann ich mir aber nicht anzeigen lassen.
                                      Das würde ich mir gerne in ioBroker als Graph anzeigen lassen.

                                      In" solar-inverter-modbus-interface-definitions-v3.0" habe ich die Adresse nicht gefunden. Aber Kachel hatte ja auch Adressen in seinem javascript, die dort nicht zu finden waren.

                                      R Offline
                                      R Offline
                                      R4
                                      wrote on last edited by
                                      #138

                                      @besimo
                                      Batterietemperatur usw. ist doch da!?
                                      z.B. javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.BatteryTemperature

                                      @alle
                                      Hat jemand einen Tipp, wie ich einen Wert ändern kann?
                                      Speziell würde ich gerne javascript.0.Solarpower.Huawei.Inverter.1.Battery.MaximumChargingPower (Register 47075) ändern um erst ab Mittags ordentlich zu laden (dann geht es bestenfalls nicht von der Einspeisung ab) und auch um eine Hysterese einzubauen.
                                      Lesen klappt ja...

                                      Insgesamt hat das Script bei mir ab und zu mal "Schluckauf" und scheint sich dann nicht mehr zu beruhigen. Erst ein Neustart hilft.
                                      Allerdings hab ich eh noch ein anderes Problem, mein Dongle beendet jeden Abend die Verbindung zum FusionSolar Server und baut sie erst morgens wieder auf. Huawei Hotline weiß auch nicht weiter bisher...

                                      B R 2 Replies Last reply
                                      0
                                      • R R4

                                        @besimo
                                        Batterietemperatur usw. ist doch da!?
                                        z.B. javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.BatteryTemperature

                                        @alle
                                        Hat jemand einen Tipp, wie ich einen Wert ändern kann?
                                        Speziell würde ich gerne javascript.0.Solarpower.Huawei.Inverter.1.Battery.MaximumChargingPower (Register 47075) ändern um erst ab Mittags ordentlich zu laden (dann geht es bestenfalls nicht von der Einspeisung ab) und auch um eine Hysterese einzubauen.
                                        Lesen klappt ja...

                                        Insgesamt hat das Script bei mir ab und zu mal "Schluckauf" und scheint sich dann nicht mehr zu beruhigen. Erst ein Neustart hilft.
                                        Allerdings hab ich eh noch ein anderes Problem, mein Dongle beendet jeden Abend die Verbindung zum FusionSolar Server und baut sie erst morgens wieder auf. Huawei Hotline weiß auch nicht weiter bisher...

                                        B Online
                                        B Online
                                        badsnoopy667
                                        wrote on last edited by badsnoopy667
                                        #139

                                        @r4
                                        Bezüglich schreiben kann ich dir meine Vorgehensweise über node-red vorschlagen:
                                        https://forum.iobroker.net/topic/51639/howto-huawei-sun2000-wr-modbus-mit-node-red-read-write
                                        Damit limitiere ich die Akku-Entladung wenn das eAuto angesteckt ist. Aber man kann genauso gut die Ladeleistung des Akkus beliebig einstellen.

                                        R 1 Reply Last reply
                                        0
                                        • B badsnoopy667

                                          @r4
                                          Bezüglich schreiben kann ich dir meine Vorgehensweise über node-red vorschlagen:
                                          https://forum.iobroker.net/topic/51639/howto-huawei-sun2000-wr-modbus-mit-node-red-read-write
                                          Damit limitiere ich die Akku-Entladung wenn das eAuto angesteckt ist. Aber man kann genauso gut die Ladeleistung des Akkus beliebig einstellen.

                                          R Offline
                                          R Offline
                                          R4
                                          wrote on last edited by
                                          #140

                                          @badsnoopy667
                                          jetzt hab ich mich schon auf JS eingeschossen, will also erst mal hier schauen ob das nicht klappt bevor ich alles lösche und mit Node-Red neu anfange...

                                          B 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          Support us

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

                                          678

                                          Online

                                          32.4k

                                          Users

                                          81.4k

                                          Topics

                                          1.3m

                                          Posts
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Home
                                          • Recent
                                          • Tags
                                          • Unread 0
                                          • Categories
                                          • Unreplied
                                          • Popular
                                          • GitHub
                                          • Docu
                                          • Hilfe