ModbusAttr an Wechselrichter SolarEdge SE10k [gelöst]

Begonnen von BenMarloe, 09 Dezember 2017, 00:14:24

Vorheriges Thema - Nächstes Thema

beejayf

Teil 2v2


sub Initialize()
{
    my $hash = shift;

    my %SolarEdgeparseInfoAll = ( %SolarEdgeparseInfo, %SolarEdgeMeter1parseInfo, %SolarEdgeBat1parseInfo );

    #require "$attr{global}{modpath}/FHEM/98_Modbus.pm";
    #require "$attr{global}{modpath}/FHEM/DevIo.pm";
   
   
    #$hash->{DefFn} = \&Define;
    #$hash->{AttrFn}     = \&Attr;
    $hash->{parseInfo}  = \%SolarEdgeparseInfoAll;    # defines registers for this Modbus Defive
    $hash->{deviceInfo} = \%SolarEdgedeviceInfo;      # defines properties of the device like
    ModbusLD_Initialize($hash);        # Generic function of the Modbus module does the rest
    #Modbus::InitializeLD($hash);                      # Generic function of the Modbus module does the rest

    $hash->{AttrList} =
        $hash->{AttrList}
      . "X_PV_Energy X_PV_EnergyToday X_PV_EnergyCurrentWeek X_PV_EnergyCurrentMonth X_Calculated_Consumption X_M_ExportedToday X_M_ExportedCurrentWeek X_M_ExportedCurrentMonth X_M_ImportedToday X_M_ImportedCurrentWeek X_M_ImportedCurrentMonth"
      . "$readingFnAttributes" . " "
      .                                               # Standard Attributes like IODEv etc
      $hash->{ObjAttrList} . " " .                    # Attributes to add or overwrite parseInfo definitions
      $hash->{DevAttrList} . " " .                    # Attributes to add or overwrite devInfo definitions
      "poll-.*" . " " .                               # overwrite poll with poll-ReadingName
      "polldelay-.*" . " " .                          # overwrite polldelay with polldelay-ReadingName
      "errorHandlingOf" . " ";                        # overwrite polldelay with polldelay-ReadingName

      return;
}
###################################
sub ExprMppt()
{                                                     # Berechnung Wert mit ScaleFactor unter Beachtung Operating_State

    # Expr, conversion of raw value to visible value
    my @vval;
    my $hash        = shift;                          # Übergabe Geräte-Hash
    my $DevName     = shift;                          # Übergabe Geräte-Name
    my $ReadingName = shift;
    $vval[0] = shift;
    $vval[1] = shift;
    $vval[2] = shift;
    $vval[3] = shift;
    $vval[4] = shift;

    # Register
    my @SolarEdge_readings =
      ( "I_AC_Current", "I_AC_Power", "I_AC_VA", "I_AC_VAR", "I_AC_PF", "I_AC_Energy_WH", "I_DC_Current", "I_DC_Voltage", "I_DC_Power" );
    my ( $Psec, $Pmin, $Phour, $Pmday, $Pmonth, $Pyear, $Pwday, $Pyday, $Pisdst ) = localtime( time() + 61 );
    my $Pyear2 = $Pyear + 1900;

    Log3 $hash, 4, "SolarEdge $DevName : " . $vval[0] . " Reg :" . $ReadingName;
   
     my $WertNeu =
        @vval . " "
      . $vval[0] . " "
      . $vval[1] . " "
      . $vval[2] . " "
      . $vval[3] . " "
      . $vval[4] ;
   
        if ( $ReadingName eq "C_Model" )
    {
        Log3 $hash, 4, "SolarEdge $DevName Model : " . $vval[0] . ":" . $vval[1] . ":" . $vval[2] . ":" . $vval[3] . ":" . $vval[4];
        $hash->{MODEL_WR} = $vval[0];
        $hash->{MODEL} = $vval[0];
        readingsBulkUpdate( $hash, $ReadingName, $vval[0] );
    }
    elsif ( $ReadingName eq "I_AC_Current" )
    {
        readingsBulkUpdate( $hash, $ReadingName,         $vval[0] * 10**$vval[4] );
        readingsBulkUpdate( $hash, $ReadingName . "_A",  $vval[1] * 10**$vval[4] );
        readingsBulkUpdate( $hash, $ReadingName . "_B",  $vval[2] * 10**$vval[4] );
        readingsBulkUpdate( $hash, $ReadingName . "_C",  $vval[3] * 10**$vval[4] );
        readingsBulkUpdate( $hash, $ReadingName . "_SF", $vval[4] );
    }
    elsif ( $ReadingName eq "I_AC_Power" || $ReadingName eq "I_DC_Power" )
    {
        my $POWER = ( $vval[0] * 10**$vval[1] );
        Log3 $hash, 4, "SolarEdge I_Power_0 : " . $vval[0] . " POWER :" . $POWER;

        if ( $POWER < 0 || $POWER > 18000 )
        {
            $POWER = 0;
        }

        Log3 $hash, 4, "SolarEdge I_Power_1 : " . $vval[0] . " POWER :" . $POWER;
        readingsBulkUpdate( $hash, $ReadingName,         $POWER );
        readingsBulkUpdate( $hash, $ReadingName . "_SF", $vval[1] );

    }
    elsif ( $ReadingName eq "I_AC_Energy_WH" )
    {
        # Anfang I_AC_Energy_WH (Today, Week,...)
        my $energy_pv   = ReadingsVal( $DevName, "X_PV_Energy", -1 );
        my $energy_time = $vval[0] * 10**$vval[1];

        if ( $energy_pv <= 0 )
        {

            readingsBulkUpdate( $hash, "X_PV_EnergyToday", "0" );
        }
        else
        {
            my $ts_energy_today = ReadingsTimestamp( $DevName, "X_PV_EnergyToday", 0 );
            my $energy_today    = ReadingsVal( $DevName, "X_PV_EnergyToday", 0 );

            my $time_now = TimeNow();
            my $date_now = substr( $time_now, 0, 10 );

            my $reading_month = substr( $ts_energy_today, 5, 2 );
            my $reading_date  = substr( $ts_energy_today, 0, 10 );

            Log3 $hash, 4, "SolarEdge TimeStamp PV-Energie: $ts_energy_today : D1: $reading_date : $time_now :  $date_now ";
            Log3 $hash, 4, "SolarEdge Jahr Monat PV-Energie: $reading_month : " . "PV_" . ($Pyear2) . "_" . ( $Pmonth + 1 ) . " ----";

            if ( $date_now eq $reading_date )
            {
                # Prüfung gleicher Tag
                #Same Day
                readingsBulkUpdate( $hash, "X_PV_EnergyToday", $energy_today + ( $energy_time - $energy_pv ) );
            }
            else
            {
                #Next Day
                my $energy_week = ReadingsVal( $DevName, "X_PV_EnergyCurrentWeek", 0 );

                readingsBulkUpdate( $hash, "X_PV_EnergyCurrentWeek", $energy_week + $energy_today );

                if ( ( $Pmonth + 1 ) eq $reading_month )
                {
                    # Prüfung gleicher Monat
                    #Same Month
                    my $energy_month = ReadingsVal( $DevName, "X_PV_EnergyCurrentMonth", 0 );

                    readingsBulkUpdate( $hash, "X_PV_EnergyCurrentMonth", $energy_month + $energy_today );
                }
                else
                {
                    # Next Month
                    my $energy_month = ReadingsVal( $DevName, "X_PV_EnergyCurrentMonth", 0 );

                    readingsBulkUpdate( $hash, "PV_" . ($Pyear2) . "_" . ($Pmonth), $energy_month );
                    readingsBulkUpdate( $hash, "X_PV_EnergyCurrentMonth",           "0" );
                }

                # New Day start at 0 again
                readingsBulkUpdate( $hash, "X_PV_EnergyToday", "0" );

                Log3 $hash, 4, "SolarEdge PV-Energie: $energy_today :  $energy_time : $energy_pv  ";
            }
        }

        readingsBulkUpdate( $hash, $ReadingName,         $vval[0] * 10**$vval[1]  );
        readingsBulkUpdate( $hash, "X_PV_Energy",        $vval[0] * 10**$vval[1]  );
        readingsBulkUpdate( $hash, $ReadingName . "_SF", $vval[1] );

       
       
       
        # Ende  I_AC_Energy_WH(Today, Week,...
    }
    else
    {
        readingsBulkUpdate( $hash, $ReadingName,         $vval[0] * 10**$vval[1] );
        readingsBulkUpdate( $hash, $ReadingName . "_SF", $vval[1] );
    }

     ############## Tabelle in STATE aufbauen ################
        my $wr_status = ReadingsVal( $DevName, "I_Status", 0 );
        my $temp = ReadingsVal( $DevName, "I_Temp_HeatSink", 0 );
        my $a_power = ReadingsVal( $DevName, "I_AC_Power", 0 );
        my $d_power = ReadingsVal( $DevName, "I_DC_Power", 0 );
        my $s_dc_voltage = ReadingsVal( $DevName, "I_DC_Voltage", 0 );
        my $s_ac_current = ReadingsVal( $DevName, "I_AC_Current", 0 );
        my $s_ac_energy = ReadingsVal( $DevName, "I_AC_Energy_WH", 0 );
        my $einheit_e = "Wh";
       
        if  ($s_ac_energy > 1000000)
        {
          $einheit_e = "MWh";
          $s_ac_energy = nearest('0.01',$s_ac_energy / 1000000);   
        } elsif ( $s_ac_energy > 1000) {
          $einheit_e = "kWh";
          $s_ac_energy = nearest('0.01',$s_ac_energy / 1000);
        }
        my $energie = $s_ac_energy." ".$einheit_e;
        my $s_teil_1 = "<table border=0 bordercolor='green' cellspacing=0 align='center'><tr><th><h1>Gesamtenergie ".$energie." </h1> </td></tr></table>";
        my $s_teil_2 = "<table border=3 bordercolor='green' cellspacing=0 align='center'><tr><th>Status</th><td>".$wr_status."</td></tr><tr><th>Temperatur</th><td align='right'>".$temp."</td></tr>";
        my $s_teil_3 = "<tr><th>Leistung DC</th><td align='right'>".$d_power." W</td></tr><tr><th>Leistung AC</th><td align='right'>".$a_power." W</td></tr><tr><th>Spannung DC</th><td align='right'>".$s_dc_voltage." V-</td></tr><tr><th>Strom AC</th><td align='right'>". $s_ac_current." A~</td></tr></table><br>";
# my $state ="<h1>Gesamtenergie ".$energie." </h1><table border=4 bordercolor='green' cellspacing=5 frame=box><tr><th>Leistung DC</th><th>Leistung AC</th><th>Spannung DC</th><th>Strom AC</th></tr><tr><td>".$d_power." W</td><td>".$a_power." W</td><td>".$s_dc_voltage." V-</td><td>". $s_ac_current." A~</td></tr></table>";
    #   my $state = "<h1>Gesamtenergie ".$energie." </h1><table border=1 bordercolor='green' cellspacing=1><tr><th>Status: ".$wr_status." </th><th>Temperatur: ".$temp." </th></tr><table><tr><th></th></tr><table border=4 bordercolor='green' cellspacing=5 frame=box><tr><th>Leistung DC</th><th>Leistung AC</th><th>Spannung DC</th><th>Strom AC</th></tr><tr><td>".$d_power." W</td><td>".$a_power." W</td><td>".$s_dc_voltage." V-</td><td>". $s_ac_current." A~</td></tr></table>";
        my $state = $s_teil_1.$s_teil_2.$s_teil_3 ;
readingsBulkUpdate($hash, "state", $state);
       ###############################################


    #if ( $ReadingName eq "I_AC_Power" )
    #{
    #    HelperConsumption( $hash, $DevName );
    #}

    Log3 $hash, 4, "SolarEdge $DevName : " . $WertNeu;
    return $WertNeu;
}

###################################
sub ExprMeter()
{    # Berechnung Wert mit ScaleFactor unter Beachtung Operating_State

    # Expr, conversion of raw value to visible value
    my @vval;
    my $hash        = shift;    # Übergabe Geräte-Hash
    my $DevName     = shift;    # Übergabe Geräte-Name
    my $ReadingName = shift;
    $vval[0] = shift;
    $vval[1] = shift;
    $vval[2] = shift;
    $vval[3] = shift;
    $vval[4] = shift;
    $vval[5] = shift;
    $vval[6] = shift;
    $vval[7] = shift;
    $vval[8] = shift;

    # Register
    my ( $Psec, $Pmin, $Phour, $Pmday, $Pmonth, $Pyear, $Pwday, $Pyday, $Pisdst ) = localtime( time() + 61 );
    my $Pyear2 = $Pyear + 1900;

    #my ($Psec,$Pmin,$Phour,$Pmday,$Pmonth,$Pyear,$Pwday,$Pyday,$Pisdst) = localtime(TimeNow());
    my $time_now = TimeNow();
    my $date_now = substr( $time_now, 0, 10 );

    Log3 $hash, 4, "SolarEdge $DevName : " . $vval[0] . " Reg :" . $ReadingName;
    my $WertNeu =
        @vval . " "
      . $vval[0] . " "
      . $vval[1] . " "
      . $vval[2] . " "
      . $vval[3] . " "
      . $vval[4] . " "
      . $vval[5] . " "
      . $vval[6] . " "
      . $vval[7] . " "
      . $vval[8];

    if ( $ReadingName eq "X_Meter_1_C_Model" )
    {
        Log3 $hash, 4, "SolarEdge $DevName X_Meter_1_C_Model : " . $vval[0] . ":" . $vval[1];
       
        if (length($vval[0]) > 4 ) {
            my $model_wr =  ReadingsVal( $DevName, "C_Model", 0 );
            $hash->{MODEL_METER} = $vval[0];
           # $hash->{MODEL_WR} = $model_wr;
            $hash->{MODEL} = $model_wr." : ".$vval[0];                  # MODEL      SE7K-RWS48BNN4 : SE-MTR-3Y-400V-A
            readingsBulkUpdate( $hash, $ReadingName, $vval[0] );
        }       
       
    }
    elsif ($ReadingName eq "X_Meter_1_M_AC_Current"
        || $ReadingName eq "X_Meter_1_M_AC_Power"
        || $ReadingName eq "X_Meter_1_M_AC_VA"
        || $ReadingName eq "X_Meter_1_M_AC_VAR"
        || $ReadingName eq "X_Meter_1_M_AC_PF" )
    {
        readingsBulkUpdate( $hash, $ReadingName,         $vval[0] * 10**$vval[4] );
        readingsBulkUpdate( $hash, $ReadingName . "_A",  $vval[1] * 10**$vval[4] );
        readingsBulkUpdate( $hash, $ReadingName . "_B",  $vval[2] * 10**$vval[4] );
        readingsBulkUpdate( $hash, $ReadingName . "_C",  $vval[3] * 10**$vval[4] );
        readingsBulkUpdate( $hash, $ReadingName . "_SF", $vval[4] );
    }
    elsif ( $ReadingName eq "X_Meter_1_M_AC_Voltage" )    #M_AC_Voltage_LN, M_AC_Voltage_AN, M_AC_Voltage_BN, M_AC_Voltage_CN, M_AC_Voltage_LL, M_AC_Voltage_AB, M_AC_Voltage_BC, M_AC_Voltage_CA, M_AC_Voltage_SF 
    {
        readingsBulkUpdate( $hash, $ReadingName . "_LN", $vval[0] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_AN", $vval[1] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_BN", $vval[2] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_CN", $vval[3] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_LL", $vval[4] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_AB", $vval[5] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_BC", $vval[6] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_CA", $vval[7] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_SF", $vval[8] );
    }
    elsif ( $ReadingName eq "X_Meter_1_M_Energy_W" )
    {
        # Anfang EXPORTED
        my $energy_exported   = ReadingsVal( $DevName, "X_Meter_1_M_Exported", -1 );
        my $exported_time       = $vval[0] * 10**$vval[8]; ## New Value X_Meter_1_M_Exported

        if ( $energy_exported <= 0 )
        {
            readingsBulkUpdate( $hash, "X_M_ExportedToday", "0" );
        }
        else
        {
            my $ts_exported_today = ReadingsTimestamp( $DevName, "X_M_ExportedToday", 0 );
            my $exported_today    = ReadingsVal( $DevName, "X_M_ExportedToday", 0 );

            my $time_now = TimeNow();
            my $date_now = substr( $time_now, 0, 10 );

            my $reading_month = substr( $ts_exported_today, 5, 2 );
            my $reading_date  = substr( $ts_exported_today, 0, 10 );

            Log3 $hash, 4, "SolarEdge TimeStamp PV-Exported: $ts_exported_today : D1: $reading_date : $time_now :  $date_now ";
            Log3 $hash, 4, "SolarEdge Jahr Monat PV-Exported: $reading_month : " . "PV_" . ($Pyear2) . "_" . ( $Pmonth + 1 ) . " ----";

            if ( $date_now eq $reading_date )
            {
                # Prüfung gleicher Tag
                #Same Day
                readingsBulkUpdate( $hash, "X_M_ExportedToday", $exported_today + ( $exported_time - $energy_exported ) );
            }
            else
            {
                #Next Day
                my $exported_week = ReadingsVal( $DevName, "X_M_ExportedCurrentWeek", 0 );

                readingsBulkUpdate( $hash, "X_M_ExportedCurrentWeek", $exported_week + $exported_today );

                if ( ( $Pmonth + 1 ) eq $reading_month )
                {
                    # Prüfung gleicher Monat
                    #Same Month
                    my $exported_month = ReadingsVal( $DevName, "X_M_ExportedCurrentMonth", 0 );

                    readingsBulkUpdate( $hash, "X_M_ExportedCurrentMonth", $exported_month + $exported_today );
                }
                else
                {
                    # Next Month
                    my $exported_month = ReadingsVal( $DevName, "X_M_ExportedCurrentMonth", 0 );

                    readingsBulkUpdate( $hash, "X_M_Exported_" . ($Pyear2) . "_" . ($Pmonth), $exported_month );
                    readingsBulkUpdate( $hash, "X_M_ExportedCurrentMonth",           "0" );
                }

                # New Day start at 0 again
                readingsBulkUpdate( $hash, "X_M_ExportedToday", "0" );

                Log3 $hash, 4, "SolarEdge PV-Exported: $exported_today :  $exported_time : $energy_exported  ";
            }
        }
        # Ende EXPORTED

        # Anfang IMPORTED
        my $energy_imported   = ReadingsVal( $DevName, "X_Meter_1_M_Imported", -1 );
        my $imported_time     = $vval[4] * 10**$vval[8]; ## New Value X_Meter_1_M_Imported

        if ( $energy_imported <= 0 )
        {
            readingsBulkUpdate( $hash, "X_M_ImportedToday", "0" );
        }
        else
        {
            my $ts_imported_today = ReadingsTimestamp( $DevName, "X_M_ImportedToday", 0 );
            my $imported_today    = ReadingsVal( $DevName, "X_M_ImportedToday", 0 );

            my $time_now = TimeNow();
            my $date_now = substr( $time_now, 0, 10 );

            my $reading_month = substr( $ts_imported_today, 5, 2 );
            my $reading_date  = substr( $ts_imported_today, 0, 10 );

            Log3 $hash, 4, "SolarEdge TimeStamp PV-Imported: $ts_imported_today : D1: $reading_date : $time_now :  $date_now ";
            Log3 $hash, 4, "SolarEdge Jahr Monat PV-Imported: $reading_month : " . "PV_" . ($Pyear2) . "_" . ( $Pmonth + 1 ) . " ----";

            if ( $date_now eq $reading_date )
            {
                # Prüfung gleicher Tag
                #Same Day
                readingsBulkUpdate( $hash, "X_M_ImportedToday", $imported_today + ( $imported_time - $energy_imported ) );
            }
            else
            {
                #Next Day
                my $imported_week = ReadingsVal( $DevName, "X_M_ImportedCurrentWeek", 0 );

                readingsBulkUpdate( $hash, "X_M_ImportedCurrentWeek", $imported_week + $imported_today );

                if ( ( $Pmonth + 1 ) eq $reading_month )
                {
                    # Prüfung gleicher Monat
                    #Same Month
                    my $imported_month = ReadingsVal( $DevName, "X_M_ImportedCurrentMonth", 0 );

                    readingsBulkUpdate( $hash, "X_M_ImportedCurrentMonth", $imported_month + $imported_today );
                }
                else
                {
                    # Next Month
                    my $imported_month = ReadingsVal( $DevName, "X_M_ImportedCurrentMonth", 0 );

                    readingsBulkUpdate( $hash, "X_M_Imported_" . ($Pyear2) . "_" . ($Pmonth), $imported_month );
                    readingsBulkUpdate( $hash, "X_M_ImportedCurrentMonth",           "0" );
                }

                # New Day start at 0 again
                readingsBulkUpdate( $hash, "X_M_ImportedToday", "0" );

                Log3 $hash, 4, "SolarEdge PV-Imported: $imported_today :  $imported_time : $energy_imported  ";
            }
        }
        # Ende IMPORTED
        # Energy Consumption kwh

        #my $energy_pv = ReadingsVal( $DevName, "I_AC_Energy_WH", -1 );
        #All Time Consumption
        #my $consumption_time = ($energy_pv - $energy_exported) + $energy_imported;

        my $imported_today = ReadingsVal( $DevName, "X_M_ImportedToday", 0 );
        my $exported_today = ReadingsVal( $DevName, "X_M_ExportedToday", 0 );
        my $pv_today       = ReadingsVal( $DevName, "X_PV_EnergyToday",  0 );

        #Consumption Today
        my $consumption_today = ($pv_today - $exported_today) +  $imported_today;

        #readingsBulkUpdate( $hash, "X_Calculated_Consumption_kWh", $consumption_time / 1000 );
        readingsBulkUpdate( $hash, "X_M_ConsumptionToday", $consumption_today );

        #Calc First then Update
        readingsBulkUpdate( $hash, "X_Meter_1_M_Exported",   $vval[0] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Exported_A", $vval[1] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Exported_B", $vval[2] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Exported_C", $vval[3] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Imported",   $vval[4] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Imported_A", $vval[5] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Imported_B", $vval[6] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Imported_C", $vval[7] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_SF",     $vval[8] );
    }
    elsif ( $ReadingName eq "X_Meter_1_M_Energy_VA" )
    {
        readingsBulkUpdate( $hash, "X_Meter_1_M_Exported_VA",   $vval[0] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Exported_VA_A", $vval[1] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Exported_VA_B", $vval[2] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Exported_VA_C", $vval[3] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Imported_VA",   $vval[4] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Imported_VA_A", $vval[5] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Imported_VA_B", $vval[6] * 10**$vval[8] );
        readingsBulkUpdate( $hash, "X_Meter_1_M_Imported_VA_C", $vval[7] * 10**$vval[8] );
        readingsBulkUpdate( $hash, $ReadingName . "_SF",        $vval[8] );
    }
    else
    {
        readingsBulkUpdate( $hash, $ReadingName,         $vval[0] * 10**$vval[1] );
        readingsBulkUpdate( $hash, $ReadingName . "_SF", $vval[1] );
    }

    #if ( $ReadingName eq "X_Meter_1_M_AC_Power" )
    #{
    #     HelperConsumption( $hash, $DevName );
    #}

    Log3 $hash, 4, "SolarEdge $DevName : " . $WertNeu;
    return $WertNeu;
}

sub HelperConsumption()
{
    my $hash    = shift;    # Übergabe Geräte-Hash
    my $DevName = shift;    # Übergabe Geräte-Name

    my $powerInverter = ReadingsVal( $DevName, "I_AC_Power",           -1 );
    my $powerGrid     = ReadingsVal( $DevName, "X_Meter_1_M_AC_Power", -1 );
    my $consumption   = $powerGrid + $powerInverter;

    # Power from grid is negativ (1 - (-1) ) = 2
    $consumption = $powerInverter - $powerGrid;

    readingsBulkUpdate( $hash, "X_Calculated_Consumption", $consumption );
    return;

}

1;

=pod
=begin html

<a name="SolarEdge"></a>
<h3>SolarEdge</h3>
<ul>
    SolarEdge uses the low level Modbus module to provide a way to communicate with SolarEdge inverter.
It defines the modbus input and holding registers and reads them in a defined interval.
  Modbusversion => Modbus 4.1.5 - 17.9.2019

  you may need to install the Math::Round module
 
  sudo apt install libmath-round-perl

<br>
    <b>Prerequisites</b>
    <ul>
        <li>
          This module requires the basic Modbus module which itsef requires Device::SerialPort or Win32::SerialPort module.
        </li>
    </ul>
    <br>

    <a name="SolarEdgeDefine"></a>
    <b>Define</b>
    <ul>
        <code>define &lt;name&gt; SolarEdge &lt;Id&gt; &lt;Interval&gt; &lt;IP&gt; &lt;Mode&gt; </code>
        <br><br>
        The module connects to the smart electrical meter with Modbus Id &lt;Id&gt; through an already defined modbus device and actively requests data from the
        smart electrical meter every &lt;Interval&gt; seconds <br>
        <br>
        Example:<br>
        <br>
        <ul><code>define SEdge SolarEdge 1 60</code></ul>
        <ul><code>define SEdge SolarEdge 3 60 192.168.0.23:502 RTU</code></ul>
    </ul>
    <br>

    <a name="SolarEdgeConfiguration"></a>
    <b>Configuration of the module</b><br><br>
    <ul>
    apart from the modbus id and the interval which both are specified in the define command there is nothing that needs to be defined.
However there are some attributes that can optionally be used to modify the behavior of the module. <br><br>
    The attributes that control which messages are sent / which data is requested every &lt;Interval&gt; seconds are:
    if the attribute is set to 1, the corresponding data is requested every &lt;Interval&gt; seconds. If it is set to 0, then the data is not requested.
   </ul>

    <a name="SolarEdgeSet"></a>
    <b>Set-Commands</b><br>
    <ul>
        The following set options are available:  none
    </ul>
<br>
    <a name="SolarEdgeGet"></a>
    <b>Get-Commands</b><br>
    <ul>
        All readings are also available as Get commands. Internally a Get command triggers the corresponding
        request to the device and then interprets the data and returns the right field value.
    </ul>
<br>
    <a name="SolarEdgeattr"></a>
    <b>Attributes</b><br><br>
    <ul>
    <li><a href="#do_not_notify">do_not_notify</a></li>
      <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
        <br>
  <li><b>X_PV_Energy</b></li>
  <li><b>X_PV_EnergyToday</b></li>
      <li><b>X_PV_EnergyCurrentWeek</b></li>
  <li><b>pv_energytomonth</b></li>
      <li><b>X_Calculated_Consumption</b> current power consumption (photovoltaik and / or grid)</li>
    </ul>
    <br>
</ul>

=end html
=cut

pejonp

@beejayf

Hallo Björn,

du kannst auch deine angepasste Datei anhängen, dann geht nichts verloren. Und ich kann ein Diff von beiden Dateien machen und das dann übernehmen.

Jörg
LaCrossGW 868MHz:WT470+TFA+TX37-IT+EMT7110+W136+WH25A HP1003+WH2621
SignalD(CC1101):Bresser+WS-0101(868MHz WH1080)+Velux KLF200+MAX!+HM-MOD-UART:Smoke HM-SEC-SD+VITOSOLIC 200 RESOL VBUS-LAN+SolarEdge SE5K(Modbus)+Sonnen!eco8(10kWh)+TD3511+DRT710M(Modbus)+ZigBee+Z-Wave+MQTT+vitoconnect

beejayf

Ah! Ein Ausflug in die erweiterten Optionen eröffnet ungeahnte Möglichkeiten :)

cocojambo

Hallo Jörg,
Hallo Björn,

ich melde mich auch noch mal. Ich habe inzwischen alle Werte die ich brauche direkt über das Modbus Modul ausgelesen und einzeln als Attribute definiert.
Damit habe ich die Batteriewerte, Inverterwerte und die Werte der beiden Modbuszähler erfassen können, wenn das auch über die Attributlösung verhältsmäßig umständlich ist.
Was mir noch ein Rätsel aufgibt sind die DC-Inverterwerte.

40096 1 I_DC_Current uint16 Amps DC Current value
40098 1 I_DC_Voltage uint16 Volts DC Voltage value
40100 1 I_DC_Power int16 Watts DC Power value


Ich habe es mit allen Kombinationen in den Attributen probiert, aber es kommen meistens die richtigen Zahlenwerte raus aber mit den falschen Stellenwerten, bzw wenn Lade-und Entladestatus wechselt (+/-) sind auch die Werte falsch.

attr obj-h40096-expr sprintf "%.1f",$val/10000
attr obj-h40096-len 4
attr obj-h40096-reading Inv_DC_Stromattr
attr obj-h40098-expr sprintf "%.1f",$val/10
attr obj-h40098-reading Inv_DC_Spannung
attr obj-h40100-expr sprintf "%.1f",$val/10
attr obj-h40100-len 1
attr obj-h40100-reading Inv_DC_Leistung
attr obj-h40100-revRegs 0
attr obj-h40100-unpack s>

Vielleicht weiß jemand von Euch welche Attribute zum Auslesen der DC-Inverterwerte nötig sind.
Die Werte aus der SolarEdge.pm funktionieren garnicht und sind ebenfalls falsch.

Gruß aus Köln
Norbert
FHEM6.2 FB7490 FB7430 3xraspi2+3+4 2xHM-LAN-CFG 2xESP CUL868 CUNO868 HUE-Bridge Harmony-Hub 5xHM-LC-Sw-PI-2 3xHM-WDS30-T2-SN 1xHM-LC_Sw4-DR 3xHM-ES-PMSw1-PI 7xFS20SIG2 6xFS20KSE 2xHM-ES-PMSW1-PL 5xS300TH 1xASH2200 1xEM1000

pejonp

#214
@cocojambo

bei diesen Registern I_DC_Current,.... usw. gibt es immer noch ein Register was für die Kommastelle und Vorzeichen ( _SF ) verantwortlich ist.
Und da das Register fürs Vorzeichen leider nach dem eigentlichen Register mit dem Wert kommt, werden in meinem Modul beide Register gleichzeitig ausgelesen und dann wird daraus der richtige Wert berechnet.


#     "h40096" => { #
    # 'reading' => 'I_DC_Current',
    #          'format' => '%.2f A',
    # },
    #     "h40097" => { #
    # 'reading' => 'I_DC_Current_SF',
    # },



Was hast du den für einen Wechselrichter ? Bei 4 oder 5 Leuten passen aber die Werte und werden mit diesem Modul ausgelesen.

pejonp
LaCrossGW 868MHz:WT470+TFA+TX37-IT+EMT7110+W136+WH25A HP1003+WH2621
SignalD(CC1101):Bresser+WS-0101(868MHz WH1080)+Velux KLF200+MAX!+HM-MOD-UART:Smoke HM-SEC-SD+VITOSOLIC 200 RESOL VBUS-LAN+SolarEdge SE5K(Modbus)+Sonnen!eco8(10kWh)+TD3511+DRT710M(Modbus)+ZigBee+Z-Wave+MQTT+vitoconnect

cocojambo

#215
Hallo Jörg,

Hat wunderbar funktioniert. Ich habe mir einige Attribute aus deinem Modul "klauen" müßen aber fast alles wird einwandfrei gelesen.
Es gibt nur zwei Werte die nach Abschalten der Batterie seltsame Werte rausgeben.

Und zwar Batt.Voltage h57712 und Batt.Current h57714


Batt_Spannung     -340282346638528859811704183484516925440.0
Batt_Status        10
Batt_Strom        -340282346638528859811704183484516925440.0


Diese Werte erscheinen aber nur wenn die Batterie softwaremäßig komplett aus ist (nachts) und der Status 10 erscheint, den ich auch nicht kenne, im Betrieb sind die Werte OK.

Hast du dafür eine Erklärung oder Lösung?

2.Frage:

Ich habe inzwischen auch mal dein Modul in Augenschein genommen und ausprobiert. Die Werte scheinen jetzt alle in Ordnung zu sein. Zumindest im Vergleich mit meinen. Ich würde dein Modul auch sehr gerne verwenden, aber ich habe zwei Modbuszähler in Betrieb, wobei der Zweite nur die Einspeisung der Solaranlage zählt. Also dort braucht man nur Spannung/Strom/Leistungsangaben. Das Auslesen der Werte zwischen den einzelnen Phasen ist da nicht nötig.

Ich habe dann gedacht, man könne in deinem Modul einfach die Adressen des Modbuszählers durch die des Zweiten ersetzen, aber so einfach scheint das nicht zu gehen. Da ich davon nur ein wenig verstehe bis hin zu Garnichts, wäre meine Frage an Dich:
Ist es mit großem Aufwand verbunden, wenn du die paar Auslesewerte des 2.Zählers in deinem Modul integrierst?

Dann brauche ich nicht mehr an meiner Lösung rumzudoktern, sondern könnte dein Modul voll verwenden, was mir natürlich lieber wäre..........

Kurze Anmerkung zu deinem Modul: In der Auswertung der Inverter_AC Werte ist noch ein Fehler. Ich habe einen 1-phasen Inverter und da kann es nur eine Spannung zwischen Phase und Null geben (ca.230V an AN oder BN oder CN) und nicht zwischen AB.

Nach Neustart des Moduls kommen im LOG ...Too many arguments....
Kann das vielleicht damit zusammenhängen....Battery_1_Instantaneous.....



Gruß aus Köln
Norbert

FHEM6.2 FB7490 FB7430 3xraspi2+3+4 2xHM-LAN-CFG 2xESP CUL868 CUNO868 HUE-Bridge Harmony-Hub 5xHM-LC-Sw-PI-2 3xHM-WDS30-T2-SN 1xHM-LC_Sw4-DR 3xHM-ES-PMSw1-PI 7xFS20SIG2 6xFS20KSE 2xHM-ES-PMSW1-PL 5xS300TH 1xASH2200 1xEM1000

pejonp

#216
@cocojambo

Hallo Norbert,

Wenn du mein Modul im Einsatz hast kannst du mal bitte ein Update machen, ich habe da jetzt noch etwas angepaßt. Vorher deine fhem.cfg sichern.


update all https://raw.githubusercontent.com/pejonp/FHEM---SolarEdge/master/controls_SolarEdge.txt



..... dev-h-combine 40 <---- in meinem Modul



Jörg

@beejayf

Hallo Böjrn,

ich habe mal die Anpassungen für die Batterie eingepflegt. Kannst du mal testen.

Jörg
LaCrossGW 868MHz:WT470+TFA+TX37-IT+EMT7110+W136+WH25A HP1003+WH2621
SignalD(CC1101):Bresser+WS-0101(868MHz WH1080)+Velux KLF200+MAX!+HM-MOD-UART:Smoke HM-SEC-SD+VITOSOLIC 200 RESOL VBUS-LAN+SolarEdge SE5K(Modbus)+Sonnen!eco8(10kWh)+TD3511+DRT710M(Modbus)+ZigBee+Z-Wave+MQTT+vitoconnect

cocojambo

Hallo Jörg,

ich habe probiert dein Modul mal zu testen. Leider hat das nicht funktioniert, weil bei mir noch das ModbusAttr Modul läuft.
Wenn ich dann dein Modul lade kommen sich beide in die "Quere" weil auch dein Modul das Modbus- und ModbusAttr Modul läd.
Ich habe keine Möglichkeit gefunden mein aktives Programm das mit ModbusAttr läuft zeitweise zu deaktivieren.
Disable und stop helfen nicht und deinstalieren des Programms welches das ModbusAttr Modul nutzt, möchte ich ja logischerweise nicht.

Wenn du eine Idee hast, wie ich beides laufen lassen kann oder mein Programm zeitweise "stilllegen" kann, teste ich dein Programm sehr gerne.

Gruß
Norbert
FHEM6.2 FB7490 FB7430 3xraspi2+3+4 2xHM-LAN-CFG 2xESP CUL868 CUNO868 HUE-Bridge Harmony-Hub 5xHM-LC-Sw-PI-2 3xHM-WDS30-T2-SN 1xHM-LC_Sw4-DR 3xHM-ES-PMSw1-PI 7xFS20SIG2 6xFS20KSE 2xHM-ES-PMSW1-PL 5xS300TH 1xASH2200 1xEM1000

beejayf

#218
@pejonp

Hallo Jörg,

Version 39 funktioniert super! Danke Dir und frohe Weihnachten!

Cheers,

Björn

PS.: ich möchte mir noch den Batteriestand in % ansehen - vielleicht kann man das über die Spannung machen - aktuell frag ich noch den Wert aus der Solaredge Cloud ab - ist ja nicht so zeitkritisch und 2-3 Minunten Lag fallen kaum auf.

pejonp

@cocojambo

Hallo Norbert,

Versuch mal eine nicht vorhandene ip adresse oder port einzutragen. Dann wird nichts mehr gefunden.
Wenn beide Module abfragen behindern sie sich.
Oder du veränderst die abfragezeit auf 5min, so das das andere Modul  die Daten lesen kann.

Jörg
LaCrossGW 868MHz:WT470+TFA+TX37-IT+EMT7110+W136+WH25A HP1003+WH2621
SignalD(CC1101):Bresser+WS-0101(868MHz WH1080)+Velux KLF200+MAX!+HM-MOD-UART:Smoke HM-SEC-SD+VITOSOLIC 200 RESOL VBUS-LAN+SolarEdge SE5K(Modbus)+Sonnen!eco8(10kWh)+TD3511+DRT710M(Modbus)+ZigBee+Z-Wave+MQTT+vitoconnect

cocojambo

Hallo Björn,

Die Batterie Ladung ist in in der Version von pejonp eigentlich schon drin.
Sie steht unter der Adresse h57732 und sieht bei mir so aus:

attr SE_Inverter obj-h57732-expr unpack("f>", $val[2].$val[3].$val[0].$val[1])
attr SE_Inverter obj-h57732-format %.1f%
attr SE_Inverter obj-h57732-len 2
attr SE_Inverter obj-h57732-reading Batt_Ladung
attr SE_Inverter obj-h57732-unpack aaaa


SE_Inverter muß du dir natürlich ersetzt denken und bei format das %-Zeichen dranhängen.

Gruß
Norbert
FHEM6.2 FB7490 FB7430 3xraspi2+3+4 2xHM-LAN-CFG 2xESP CUL868 CUNO868 HUE-Bridge Harmony-Hub 5xHM-LC-Sw-PI-2 3xHM-WDS30-T2-SN 1xHM-LC_Sw4-DR 3xHM-ES-PMSw1-PI 7xFS20SIG2 6xFS20KSE 2xHM-ES-PMSW1-PL 5xS300TH 1xASH2200 1xEM1000

cocojambo

@pejonp

Hallo Jörg,

ich habe die IP-Adresse geändert und das andere Modul geht dann auf disconnect.
Dann habe ich versucht dein Update zu laden.
update all https://raw.githubusercontent.com/pejonp/FHEM---SolarEdge/master/controls_SolarEdge.txt
Funktioniert nicht. Es wird das übliche Backup gemacht und dann steht im Im Log "Nothing to do..."
Ich habe darauf hin die 98_SolarEdge.pm unter FHEM/ gelöscht und noch mal probiert das Modul herunter zu laden.
Das gleiche "Nothing to do..."
Das Modul ist auch nicht im Verzeichniss vorhanden.

Warum geht das nicht?

Gruß
Norbert
FHEM6.2 FB7490 FB7430 3xraspi2+3+4 2xHM-LAN-CFG 2xESP CUL868 CUNO868 HUE-Bridge Harmony-Hub 5xHM-LC-Sw-PI-2 3xHM-WDS30-T2-SN 1xHM-LC_Sw4-DR 3xHM-ES-PMSw1-PI 7xFS20SIG2 6xFS20KSE 2xHM-ES-PMSW1-PL 5xS300TH 1xASH2200 1xEM1000

pejonp

@cocojambo

Hallo Norbert,

lösche mal bitte auch die

controls_SolarEdge.txt


Wenn das dann auch nicht geht, einfach die 98_SolarEdge.pm vom github einkopieren. Aber danach die Rechte/Eigentümer "fhem/dialout" anpassen.
Einen Restart von FHEM nicht vergessen.

@beejayf

Hallo Börn,

ich habe die beiden Register für den Ladezustand der Batterie mit aufgenommen. Bitte einmal testen.

Jörg

Schönen 3. Advent
LaCrossGW 868MHz:WT470+TFA+TX37-IT+EMT7110+W136+WH25A HP1003+WH2621
SignalD(CC1101):Bresser+WS-0101(868MHz WH1080)+Velux KLF200+MAX!+HM-MOD-UART:Smoke HM-SEC-SD+VITOSOLIC 200 RESOL VBUS-LAN+SolarEdge SE5K(Modbus)+Sonnen!eco8(10kWh)+TD3511+DRT710M(Modbus)+ZigBee+Z-Wave+MQTT+vitoconnect

beejayf

@pejonp

Hallo Jörg,

ja sieht gut aus - eben das Update gemacht und im Wert Battery_1_SOE steht die 10 (%), was sich mit dem Wert in der Cloud deckt. Wenn morgen die Sonne scheint checke ich das nochmal.

Hohoho,

Björn

Chris_XXX

Hallo zusammen,

ich habe das Modul von ~10.2018 im Einsatz. Seitdem habe ich es nicht mehr geändert. Jetzt habe ich meine Anlage um ein Smartmeter erweitert. Die Werte bekomme ich am WR angezeigt. Diese möchte ich nun auch in FHEM sehen. Ich habe dazu die neueste Version des Moduls installiert. Danach hat leider nicht mehr viel funktioniert:
2020.12.28 12:26:13 1: Messages collected while initializing FHEM:configfile: Cannot load module SolarEdge
Please define SolarEdge 5c481c13-f33f-4f30-f3a1-7526220148935a5d first
Muss ich das Device neu anlegen oder hat jemand einen Tip für mich?
Die Modbus Module habe ich auch mit upgedated. Ebenfalls libmath-round-perl installiert.

Viele Grüße
Christian