Solaredge inverter via Modbus TCP 2

(Part 3/3)

solaredge.rules (part 2/2)

rule SE2K_M_Exported_Scaling
when 
    Item SE2KM_ScaleAll changed to ON or
    Item SE2K_M_Exported_int changed
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Werteskalierung - SE2K_M_Exported - '

    // Skalierungsfaktor normieren
    var Double scalingFactor = (SE2K_M_Energy_W_SF_int.state as DecimalType).doubleValue
    if (scalingFactor > 32767) scalingFactor = scalingFactor - (65536).doubleValue

    // Wert skalieren
    var Double result = (SE2K_M_Exported_int.state as DecimalType).doubleValue * Math::pow(10,scalingFactor)

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Rohwert: ' + SE2K_M_Exported_int.state.toString + ', SF: 10^' + SE2K_M_Energy_W_SF_int.state.toString + '; skaliert: ' + result.toString)
    SE2K_M_Exported.postUpdate(result)
end

rule SE2K_M_Exported_A_Scaling
when 
    Item SE2KM_ScaleAll changed to ON or
    Item SE2K_M_Exported_A_int changed
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Werteskalierung - SE2K_M_Exported_A - '

    // Skalierungsfaktor normieren
    var Double scalingFactor = (SE2K_M_Energy_W_SF_int.state as DecimalType).doubleValue
    if (scalingFactor > 32767) scalingFactor = scalingFactor - (65536).doubleValue

    // Wert skalieren
    var Double result = (SE2K_M_Exported_A_int.state as DecimalType).doubleValue * Math::pow(10,scalingFactor)

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Rohwert: ' + SE2K_M_Exported_A_int.state.toString + ', SF: 10^' + SE2K_M_Energy_W_SF_int.state.toString + '; skaliert: ' + result.toString)
    SE2K_M_Exported_A.postUpdate(result)
end

rule SE2K_M_Exported_B_Scaling
when 
    Item SE2KM_ScaleAll changed to ON or
    Item SE2K_M_Exported_B_int changed
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Werteskalierung - SE2K_M_Exported_B - '

    // Skalierungsfaktor normieren
    var Double scalingFactor = (SE2K_M_Energy_W_SF_int.state as DecimalType).doubleValue
    if (scalingFactor > 32767) scalingFactor = scalingFactor - (65536).doubleValue

    // Wert skalieren
    var Double result = (SE2K_M_Exported_B_int.state as DecimalType).doubleValue * Math::pow(10,scalingFactor)

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Rohwert: ' + SE2K_M_Exported_B_int.state.toString + ', SF: 10^' + SE2K_M_Energy_W_SF_int.state.toString + '; skaliert: ' + result.toString)
    SE2K_M_Exported_B.postUpdate(result)
end

rule SE2K_M_Exported_C_Scaling
when 
    Item SE2KM_ScaleAll changed to ON or
    Item SE2K_M_Exported_C_int changed
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Werteskalierung - SE2K_M_Exported_C - '

    // Skalierungsfaktor normieren
    var Double scalingFactor = (SE2K_M_Energy_W_SF_int.state as DecimalType).doubleValue
    if (scalingFactor > 32767) scalingFactor = scalingFactor - (65536).doubleValue

    // Wert skalieren
    var Double result = (SE2K_M_Exported_C_int.state as DecimalType).doubleValue * Math::pow(10,scalingFactor)

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Rohwert: ' + SE2K_M_Exported_C_int.state.toString + ', SF: 10^' + SE2K_M_Energy_W_SF_int.state.toString + '; skaliert: ' + result.toString)
    SE2K_M_Exported_C.postUpdate(result)
end

rule SE2K_M_Imported_Scaling
when 
    Item SE2KM_ScaleAll changed to ON or
    Item SE2K_M_Imported_int changed
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Werteskalierung - SE2K_M_Imported - '

    // Skalierungsfaktor normieren
    var Double scalingFactor = (SE2K_M_Energy_W_SF_int.state as DecimalType).doubleValue
    if (scalingFactor > 32767) scalingFactor = scalingFactor - (65536).doubleValue

    // Wert skalieren
    var Double result = (SE2K_M_Imported_int.state as DecimalType).doubleValue * Math::pow(10,scalingFactor)

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Rohwert: ' + SE2K_M_Imported_int.state.toString + ', SF: 10^' + SE2K_M_Energy_W_SF_int.state.toString + '; skaliert: ' + result.toString)
    SE2K_M_Imported.postUpdate(result)
end

rule SE2K_M_Imported_A_Scaling
when 
    Item SE2KM_ScaleAll changed to ON or
    Item SE2K_M_Imported_A_int changed
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Werteskalierung - SE2K_M_Imported_A - '

    // Skalierungsfaktor normieren
    var Double scalingFactor = (SE2K_M_Energy_W_SF_int.state as DecimalType).doubleValue
    if (scalingFactor > 32767) scalingFactor = scalingFactor - (65536).doubleValue

    // Wert skalieren
    var Double result = (SE2K_M_Imported_A_int.state as DecimalType).doubleValue * Math::pow(10,scalingFactor)

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Rohwert: ' + SE2K_M_Imported_A_int.state.toString + ', SF: 10^' + SE2K_M_Energy_W_SF_int.state.toString + '; skaliert: ' + result.toString)
    SE2K_M_Imported_A.postUpdate(result)
end

rule SE2K_M_Imported_B_Scaling
when 
    Item SE2KM_ScaleAll changed to ON or
    Item SE2K_M_Imported_B_int changed
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Werteskalierung - SE2K_M_Imported_B - '

    // Skalierungsfaktor normieren
    var Double scalingFactor = (SE2K_M_Energy_W_SF_int.state as DecimalType).doubleValue
    if (scalingFactor > 32767) scalingFactor = scalingFactor - (65536).doubleValue

    // Wert skalieren
    var Double result = (SE2K_M_Imported_B_int.state as DecimalType).doubleValue * Math::pow(10,scalingFactor)

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Rohwert: ' + SE2K_M_Imported_B_int.state.toString + ', SF: 10^' + SE2K_M_Energy_W_SF_int.state.toString + '; skaliert: ' + result.toString)
    SE2K_M_Imported_B.postUpdate(result)
end

rule SE2K_M_Imported_C_Scaling
when 
    Item SE2KM_ScaleAll changed to ON or
    Item SE2K_M_Imported_C_int changed
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Werteskalierung - SE2K_M_Imported_C - '

    // Skalierungsfaktor normieren
    var Double scalingFactor = (SE2K_M_Energy_W_SF_int.state as DecimalType).doubleValue
    if (scalingFactor > 32767) scalingFactor = scalingFactor - (65536).doubleValue

    // Wert skalieren
    var Double result = (SE2K_M_Imported_C_int.state as DecimalType).doubleValue * Math::pow(10,scalingFactor)

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Rohwert: ' + SE2K_M_Imported_C_int.state.toString + ', SF: 10^' + SE2K_M_Energy_W_SF_int.state.toString + '; skaliert: ' + result.toString)
    SE2K_M_Imported_C.postUpdate(result)
end

// Eigenverbrauch (Direktverbrauch) = Erzeugung - Einspeisung
rule SE2KM_EigenverbrauchGesamt
when
    Item SE2K_I_AC_Energy_WH received update or
    Item SE2K_M_Exported received update 
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Berechnungen - SE2KM_EigenverbrauchGesamt - '

    // Eigenverbrauch berechnen
    var Double result = 0.0
    if (SE2K_I_AC_Energy_WH.state != NULL && SE2K_M_Exported.state != NULL) {
        result = (SE2K_I_AC_Energy_WH.state as QuantityType<Energy>).doubleValue - (SE2K_M_Exported.state as QuantityType<Energy>).doubleValue
    }

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Eigenverbrauch: ' + SE2KM_EigenverbrauchGesamt.state.toString + '; Produktion: ' + SE2K_I_AC_Energy_WH.state.toString + ', Export: ' + SE2K_M_Exported.state.toString)
    SE2KM_EigenverbrauchGesamt.postUpdate(result)
end

// Gesamtverbrauch = Bezug + Erzeugung - Einspeisung
rule SE2KM_GesamtverbrauchGesamt
when
    Item SE2K_I_AC_Energy_WH received update or
    Item SE2K_M_Imported received update or
    Item SE2K_M_Exported received update
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Berechnungen - SE2KM_GesamtverbrauchGesamt - '

    // Eigenverbrauch berechnen
    var Double result = 0.0
    if (SE2K_M_Imported.state != NULL && SE2K_I_AC_Energy_WH.state != NULL && SE2K_M_Exported.state != NULL) {
        result = (SE2K_M_Imported.state as QuantityType<Energy>).doubleValue + (SE2K_I_AC_Energy_WH.state as QuantityType<Energy>).doubleValue - (SE2K_M_Exported.state as QuantityType<Energy>).doubleValue
    }
    
    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Gesamtverbrauch: ' + SE2KM_GesamtverbrauchGesamt.state.toString + '; Produktion: ' + SE2K_I_AC_Energy_WH.state.toString + ', Import: ' + SE2K_M_Imported.state.toString + ', Export: ' + SE2K_M_Exported.state.toString)
    SE2KM_GesamtverbrauchGesamt.postUpdate(result)
end

// Solarer Deckungsgrad = Eigenverbrauch / Gesamtverbrauch
rule SE2KM_SolarerDeckungsgradGesamt
when
    Item SE2KM_EigenverbrauchGesamt received update or
    Item SE2KM_GesamtverbrauchGesamt received update
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Berechnungen - SE2KM_SolarerDeckungsgradGesamt - '

    // Solarer Deckungsgrad berechnen
    var Double result = 0.0
    if (SE2KM_EigenverbrauchGesamt.state != NULL && SE2KM_GesamtverbrauchGesamt.state != NULL) {
        result = (SE2KM_EigenverbrauchGesamt.state as QuantityType<Energy>).doubleValue / (SE2KM_GesamtverbrauchGesamt.state as QuantityType<Energy>).doubleValue * 100.0
    }

    // Float-Wert schreiben
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Solarer Deckungsgrad: ' + SE2KM_SolarerDeckungsgradGesamt.state.toString + '; Eigenverbrauch: ' + SE2KM_EigenverbrauchGesamt.state.toString + ', Gesamtverbrauch: ' + SE2KM_GesamtverbrauchGesamt.state.toString)
    SE2KM_SolarerDeckungsgradGesamt.postUpdate(result)
end

rule SE2KM_VerbraeucheMomentan
when 
    Item SE2K_M_AC_Power received update
then
    Thread::sleep(100)						// Let modbus finish reading all registers
    val String logPrefix = 'SolarEdge Berechnungen - SE2KM_VerbraeucheMomentan - '

    var Double erzeugung = (SE2K_I_AC_Power.state as QuantityType<Power>).doubleValue
    // gridpower = bezug - einspeisung
    var Double gridpower = (SE2K_M_AC_Power.state as QuantityType<Power>).doubleValue
    var Double verbrauch = erzeugung + gridpower
    // Direktverbrauch = Erzeugung - Einspeisung
    var Double direktverbrauch = 0.0

    // Leistung Haus (momentan) = Gesamtleistung Haus (Erzeugung + Bezug + Einspeisung)
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Hausverbrauch Momentan: ' + SE2KM_HausverbrauchMomentan.state.toString)
    SE2KM_HausverbrauchMomentan.postUpdate(verbrauch)
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Netzbezug Momentan: ' + SE2KM_NetzleistungMomentan.state.toString)
    SE2KM_NetzleistungMomentan.postUpdate(gridpower)
    
    if (gridpower < 0.0) {
        direktverbrauch = erzeugung + gridpower
    } else if (gridpower > 0.0) {
        direktverbrauch = erzeugung
    }
    
    if (EnableLog_SolarEdgeRules.state == ON) logInfo('solaredge.rules', logPrefix + 'Direktverbrauch Momentan: ' + SE2KM_DirektverbrauchMomentan.state.toString)
    SE2KM_DirektverbrauchMomentan.postUpdate(direktverbrauch)
end

Excerpt from my sitemap

Frame label="PV-Anlage" {
	Default item=SE2K_I_Status_int label="Wechselrichter Status" icon="switch"
	Default item=SE2K_I_Status_Vendor_int label="Wechselrichter Störung [%d]" icon="error"
	Default item=SE2K_I_AC_Power label="AC-Seite Wirkleistung (momentan) [%.1f W]"
	Default item=SE2K_I_DC_Power label="DC-Seite Leistung (momentan) [%.1f W]"
	Default item=SE2K_I_AC_PF label="Leistungsfaktor" icon="line"
	Default item=SE2K_I_AC_Energy_WH label="Stromerzeugung (gesamt) [%.2f MWh]"
	Default item=SE2K_M_Exported label="PV Meter EinspeisezÀhler Wirkenergie (Summe) [%.2f MWh]"
	Default item=SE2KM_EigenverbrauchGesamt label="Eigenverbrauch Gesamt [%.2f MWh]"
	Default item=SE2KM_GesamtverbrauchGesamt label="Gesamtverbrauch Gesamt [%.2f MWh]"
	Default item=SE2KM_SolarerDeckungsgradGesamt label="SolarerDeckungsgrad Gesamt [%.2f %%]" icon="line"
	Text item=gSE2K label="Wechselrichter PV-Anlage (float-Werte, skaliert)" icon="solarplant" {
		Default item=SE2K_I_AC_CurrentA label="PV WR AC Strom gesamt"
		Default item=SE2K_I_AC_VoltageAB label="PV WR AC Spannung"
		Default item=SE2K_I_AC_Power label="PV WR AC Wirkleistung"
		Default item=SE2K_I_AC_Frequency label="PV WR Netzfrequenz"
		Default item=SE2K_I_AC_VA label="PV WR AC Scheinleistung"
		Default item=SE2K_I_AC_VAR label="PV WR AC Blindleistung"
		Default item=SE2K_I_AC_PF label="PV WR AC Leistungsfaktor"
		Default item=SE2K_I_AC_Energy_WH label="PV WR AC Erzeugungszaehler"
		Default item=SE2K_I_DC_Current label="PV WR DC Strom"
		Default item=SE2K_I_DC_Voltage label="PV WR DC Spannung"
		Default item=SE2K_I_DC_Power label="PV WR DC Leistung"
		Default item=SE2K_I_TempSink label="PV WR Temperatur KĂŒhlplatte"
		Default item=SE2K_ScaleAll label="Alle SE2K-Skalierungsregeln ausfĂŒhren"
	}
	Text item=gSE2KM label="Meter PV-Anlage (float-Werte, skaliert)" icon="solarplant" {
		Default item=SE2K_M_AC_Current label="PV Meter AC Strom (Summe)"
		Default item=SE2K_M_AC_Current_calc label="PV Meter AC Strom (Summe, berechnet)"
		Default item=SE2K_M_AC_Current_A label="PV Meter AC Strom Phase A"
		Default item=SE2K_M_AC_Current_A_calc label="PV Meter AC Strom Phase A (berechnet)"
		Default item=SE2K_M_AC_Current_B label="PV Meter AC Strom Phase B"
		Default item=SE2K_M_AC_Current_B_calc label="PV Meter AC Strom Phase B (berechnet)"
		Default item=SE2K_M_AC_Current_C label="PV Meter AC Strom Phase C"
		Default item=SE2K_M_AC_Current_C_calc label="PV Meter AC Strom Phase C (berechnet)"
		Default item=SE2K_M_AC_Voltage_LN label="PV Meter Spannung LN (Avg.)"
		Default item=SE2K_M_AC_Voltage_AN label="PV Meter Spannung AN"
		Default item=SE2K_M_AC_Voltage_BN label="PV Meter Spannung BN"
		Default item=SE2K_M_AC_Voltage_CN label="PV Meter Spannung CN"
		Default item=SE2K_M_AC_Power label="PV Meter Wirkleistung (Summe)"
		Default item=SE2K_M_AC_Power_A label="PV Meter Wirkleistung Phase A"
		Default item=SE2K_M_AC_Power_B label="PV Meter Wirkleistung Phase B"
		Default item=SE2K_M_AC_Power_C label="PV Meter Wirkleistung Phase C"
		Default item=SE2K_M_AC_VA label="PV Meter Scheinleistung (Summe)"
		Default item=SE2K_M_AC_VA_A label="PV Meter Scheinleistung Phase A"
		Default item=SE2K_M_AC_VA_B label="PV Meter Scheinleistung Phase B"
		Default item=SE2K_M_AC_VA_C label="PV Meter Scheinleistung Phase C"
		Default item=SE2K_M_AC_PF label="PV Meter Leistungsfaktor (Avg.)"
		Default item=SE2K_M_AC_PF_A label="PV Meter Leistungsfaktor Phase A"
		Default item=SE2K_M_AC_PF_B label="PV Meter Leistungsfaktor Phase B"
		Default item=SE2K_M_AC_PF_C label="PV Meter Leistungsfaktor Phase C"
		Default item=SE2K_M_Exported label="PV Meter EinspeisezÀhler Wirkenergie (Summe)"
		Default item=SE2K_M_Exported_A label="PV Meter EinspeisezÀhler Wirkenergie Phase A"
		Default item=SE2K_M_Exported_B label="PV Meter EinspeisezÀhler Wirkenergie Phase B"
		Default item=SE2K_M_Exported_C label="PV Meter EinspeisezÀhler Wirkenergie Phase C"
		Default item=SE2K_M_Imported label="PV Meter BezugszÀhler Wirkenergie (Summe)"
		Default item=SE2K_M_Imported_A label="PV Meter BezugszÀhler Wirkenergie Phase A"
		Default item=SE2K_M_Imported_B label="PV Meter BezugszÀhler Wirkenergie Phase B"
		Default item=SE2K_M_Imported_C label="PV Meter BezugszÀhler Wirkenergie Phase C"
		Default item=SE2KM_EigenverbrauchGesamt label="Eigenverbrauch Gesamt"
		Default item=SE2KM_GesamtverbrauchGesamt label="Gesamtverbrauch Gesamt"
		Default item=SE2KM_SolarerDeckungsgradGesamt label="SolarerDeckungsgrad Gesamt"
		Default item=SE2KM_DirektverbrauchMomentan label="Direktverbrauch Momentan"
		Default item=SE2KM_HausverbrauchMomentan label="Hausverbrauch Momentan"
		Default item=SE2KM_NetzleistungMomentan label="Netzleistung Momentan"
		Default item=SE2K_M_AC_Freq label="PV Meter Frequenz"
		Default item=SE2KM_ScaleAll label="Alle SE2KM-Skalierungsregeln ausfĂŒhren"
	}
	Text item=gSE2KStat label="Wechselrichter PV-Anlage (Status-Werte, nicht skalierbar)" icon="solarplant" {
		Default item=SE2K_C_SunSpec_DID_int label="PV WR Typ"
		Default item=SE2K_C_SunSpec_Length_int label="PV WR Sunspec Datensatz LĂ€nge (int)"
		Default item=SE2K_I_Status_int label="PV WR Status"
		Default item=SE2K_I_Status_Vendor_int label="PV WR Status (SE-spezifisch)"
	}
	Text item=gSE2KMStat label="Meter PV-Anlage (Status-Werte, nicht skalierbar)" icon="solarplant" {
		Default item=SE2K_M_C_SunSpec_DID_int label="PV Meter Typ"
		Default item=SE2K_M_C_SunSpec_Length_int label="PV Meter Sunspec Datensatz LĂ€nge (int)"
		Default item=SE2K_M_Events_int label="PV Meter Events"
	}
	Text item=gSE2KInt label="Wechselrichter PV-Anlage (int-Werte, skalierbar)" icon="solarplant" {
		Default item=SE2K_I_AC_Power_int label="PV WR AC Leistung (int)"
		Default item=SE2K_I_AC_Frequency_int label="PV WR AC Frequenz (int)"
		Default item=SE2K_I_AC_VA_int label="PV WR AC Scheinleistung (int)"
		Default item=SE2K_I_AC_VAR_int label="PV WR AC Blindleistung (int)"
		Default item=SE2K_I_AC_PF_int label="PV WR AC Leistungsfaktor (int)"
		Default item=SE2K_I_AC_Energy_WH_int label="PV WR AC Erzeugungszaehler (int)"
		Default item=SE2K_I_DC_Current_int label="PV WR DC Strom (int)"
		Default item=SE2K_I_DC_Voltage_int label="PV WR DC Spannung (int)"
		Default item=SE2K_I_DC_Power_int label="PV WR DC Leistung (int)"
		Default item=SE2K_I_TempSink_int label="PV WR Temperatur KĂŒhlplatte (int)"
	}
	Text item=gSE2KMInt label="Meter PV-Anlage (int-Werte, skalierbar)" icon="solarplant" {
		Default item=SE2K_M_AC_Current_int label="PV Meter AC Strom (Summe) (int)"
		Default item=SE2K_M_AC_Current_A_int label="PV Meter AC Strom Phase A (int)"
		Default item=SE2K_M_AC_Current_B_int label="PV Meter AC Strom Phase B (int)"
		Default item=SE2K_M_AC_Current_C_int label="PV Meter AC Strom Phase C (int)"
		Default item=SE2K_M_AC_Voltage_LN_int label="PV Meter Spannung LN (Avg.) (int)"
		Default item=SE2K_M_AC_Voltage_AN_int label="PV Meter Spannung AN (int)"
		Default item=SE2K_M_AC_Voltage_BN_int label="PV Meter Spannung BN (int)"
		Default item=SE2K_M_AC_Voltage_CN_int label="PV Meter Spannung CN (int)"
		Default item=SE2K_M_AC_Freq_int label="PV Meter Frequenz (int)"
		Default item=SE2K_M_AC_Power_int label="PV Meter Wirkleistung (Summe) (int)"
		Default item=SE2K_M_AC_Power_A_int label="PV Meter Wirkleistung Phase A (int)"
		Default item=SE2K_M_AC_Power_B_int label="PV Meter Wirkleistung Phase B (int)"
		Default item=SE2K_M_AC_Power_C_int label="PV Meter Wirkleistung Phase C (int)"
		Default item=SE2K_M_AC_VA_int label="PV Meter Scheinleistung (Summe) (int)"
		Default item=SE2K_M_AC_VA_A_int label="PV Meter Scheinleistung Phase A (int)"
		Default item=SE2K_M_AC_VA_B_int label="PV Meter Scheinleistung Phase B (int)"
		Default item=SE2K_M_AC_VA_C_int label="PV Meter Scheinleistung Phase C (int)"
		Default item=SE2K_M_AC_PF_int label="PV Meter Leistungsfaktor (Avg.) (int)"
		Default item=SE2K_M_AC_PF_A_int label="PV Meter Leistungsfaktor Phase A (int)"
		Default item=SE2K_M_AC_PF_B_int label="PV Meter Leistungsfaktor Phase B (int)"
		Default item=SE2K_M_AC_PF_C_int label="PV Meter Leistungsfaktor Phase C (int)"
		Default item=SE2K_M_Exported_int label="PV Meter EinspeisezÀhler Wirkenergie (Summe) (int)"
		Default item=SE2K_M_Exported_A_int label="PV Meter EinspeisezÀhler Wirkenergie Phase A (int)"
		Default item=SE2K_M_Exported_B_int label="PV Meter EinspeisezÀhler Wirkenergie Phase B (int)"
		Default item=SE2K_M_Exported_C_int label="PV Meter EinspeisezÀhler Wirkenergie Phase C (int)"
		Default item=SE2K_M_Imported_int label="PV Meter BezugszÀhler Wirkenergie (Summe) (int)"
		Default item=SE2K_M_Imported_A_int label="PV Meter BezugszÀhler Wirkenergie Phase A (int)"
		Default item=SE2K_M_Imported_B_int label="PV Meter BezugszÀhler Wirkenergie Phase B (int)"
		Default item=SE2K_M_Imported_C_int label="PV Meter BezugszÀhler Wirkenergie Phase C (int)"
	}
	Text item=gSE2KSfInt label="Wechselrichter PV-Anlage Skalierungsfaktoren (int-Werte)" icon="solarplant" {
		Default item=SE2K_I_AC_Current_SF_int label="PV WR AC Strom Ph.A SF (int)"
		Default item=SE2K_I_AC_Voltage_SF_int label="PV WR AC Spannung SF (int)"
		Default item=SE2K_I_AC_Power_SF_int label="PV WR AC Leistung SF (int)"
		Default item=SE2K_I_AC_Frequency_SF_int label="PV WR AC Frequenz SF (int)"
		Default item=SE2K_I_AC_VA_SF_int label="PV WR AC Scheinleistung SF (int)"
		Default item=SE2K_I_AC_VAR_SF_int label="PV WR AC Blindleistung SF (int)"
		Default item=SE2K_I_AC_PF_SF_int label="PV WR AC Leistungsfaktor SF (int)"
		Default item=SE2K_I_AC_Energy_WH_SF_int label="PV WR AC Erzeugungszaehler SF (int)"
		Default item=SE2K_I_DC_Current_SF_int label="PV WR DC Strom SF (int)"
		Default item=SE2K_I_DC_Voltage_SF_int label="PV WR DC Spannung SF (int)"
		Default item=SE2K_I_DC_Power_SF_int label="PV WR DC Leistung SF (int)"
		Default item=SE2K_I_TempSink_SF_int label="PV WR Temperatur KĂŒhlplatte SF (int)"
	}
	Text item=gSE2KMSfInt label="Meter PV-Anlage Skalierungsfaktoren (int-Werte)" icon="solarplant" {
		Default item=SE2K_M_AC_Current_SF_int label="PV Meter AC Strom SF (int)"
		Default item=SE2K_M_AC_Voltage_SF_int label="PV Meter Spannung SF (int)"
		Default item=SE2K_M_AC_Freq_SF_int label="PV Meter Frequenz SF (int)"
		Default item=SE2K_M_AC_Power_SF_int label="PV Meter Wirkleistung SF"
		Default item=SE2K_M_AC_VA_SF_int label="PV Meter Scheinleistung SF (int)"
		Default item=SE2K_M_AC_PF_SF_int label="PV Meter Leistungsfaktor SF (int)"
		Default item=SE2K_M_Energy_W_SF_int label="PV Meter ZĂ€hler Wirkenergie SF (int)"
	}
}

solaredgeInverterType.map

//  SE2000 Inverter Type Values
//	The following C_SunSpec_DID values are supported:
//	Value 					Description
//	101 					single phase
//	102 					split phase
//	103 					three phase

101=Single phase
102=Split phase
103=Three phase

solaredgeMeterType.map

//  SE2000 Inverter Type Values
//	The following C_SunSpec_DID values are supported:
//  Well-known value. Uniquely identifies this as a SunSpecMODBUS Map:
//	Value       Description
//  201         Single Phase (AN or AB) Meter
//  202         Split Single Phase (ABN) Meter
//  203         WYE-Connect Three Phase (ABCN) Meter
//  204         Delta-Connect Three Phase (ABC) Meter
    
201=Single Phase (AN or AB) Meter
202=Split Single Phase (ABN) Meter
203=WYE-Connect Three Phase (ABCN) Meter
204=Delta-Connect Three Phase (ABC) Meter

solaredgeStatus.map

//  SE2000 Inverter Device Status Values
//	The following I_Status_ xxxx values are supported:
//	Parameter 				Value 					Description
//	I_STATUS_OFF 				1 					Off
//	I_STATUS_SLEEPING 			2 					Sleeping (auto-shutdown) – Night mode
//	I_STATUS_STARTING 			3 					Grid Monitoring/wake-up
//	I_STATUS_MPPT 				4 					Inverter is ON and producing power
//	I_STATUS_THROTTLED 			5 					Production (curtailed)
//	I_STATUS_SHUTTING_DOWN 		6 					Shutting down
//	I_STATUS_FAULT 				7 					Fault
//	I_STATUS_STANDBY 			8 					Maintenance/setup

1=Aus
2=Nachtmodus
3=Startet
4=Produktion
5=Gedrosselt
6=Stoppt
7=Fehler
8=Setup
=Undefined

I have put some of the values into persistence to analyse it with grafana. This looks as follows:

Excerpt from my influxdb.persist:

Strategies {
       everyHour : "0 0 * * * ?"
       everyDay  : "0 0 0 * * ?"
       every15min: "*/15 * * * * ?" 
       default = everyChange
}

Items {
       gSE2KMMomentan*, SE2K_I_AC_Power : strategy = everyChange, every15min
}

This setup works like a charm since over three months now!
Maybe I can help anyone with that. Feel free to ask, if there is any question.

Have fun!

Cheers
Jonathan

3 Likes

Hi Jonathan,
thanks a lot for the code.

I created all files and copied the content. In the things file I changed the IP and Port to my address.
Sitemap shows NACHTMODUS so I assume it is somehow connected.

Unfortunately my error log is running full of errors:

<2020-06-18 23:06:10.317 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘SE2K_I_AC_VoltageAB_Scaling’: The name ‘EnableLog_SolarEdgeRules’ cannot be resolved to an item or type; line 50, column 9, length 24>

and many more of those.

I have a different inverter: SE15K, which is a 3 phase inverter. Could that be the problem? Does it make sense to adapt your script at all, as it only refers to a single phase if I understand it correctly.

Thank you very much for your help.
Kind regards
Florian

Hi @Flo,

oops, it seems I missed to add one file to my solution above. The errors come from items which you haven’t defined yet (unintendedly)

I have some Items to enable and disable the debug outputs of my rules to keep them a bit cleaner when everything runs perfect. In case I have to debug something I enable them quickly by these items via BasicUI or whatever UI you want.

debug.items:

// Groups
Group	gEnableLog						"Freigabe Debug-Logs"						<settings>
// Items
Switch	EnableLog_SolarEdgeRules		"Freigabe Debug-Log solaredge.rules"					(gEnableLog)

I additionally use mapDB persistence to persist the states of the debug enable switches:
mapdb.persist:

Strategies {
  default = everyUpdate
}
Items {
        gEnableLog* : strategy = everyChange, restoreOnStartup
}

The switches shown in BasicUI:
image

I hope this helps!

BTW: for your three phase inverter, I think you just have to comment-in the lines which I commented out, because I don’t use them (e.g. in modbusSolaredge.things the line starting with //Thing data I_AC_CurrentB... and so on).

Cheers
Jonathan

Hi Jonathan (@elektrolubach),

I successfullly used your settings where I have another SolarEdge setup:
Two PhaseInverters: SE4000H and SE2200H, where the SE4000H is the Master, both single phase.
In addidtion a LG Battery RESU 10 H

Do you know or give me some hints how or at which places I have to enrich my (your) settings? Of course I need to add some more registers in things-file, but perhaps you can point me to the correct registers to use.

Thanks for your answers in advance,
Ralf

Hi @shotte,

I do not exactly know what you are targeting on, but the best resource is this:
Technical Note – SunSpec Logging in SolarEdge Inverters

Starting from page 15, the registers and the meanings of enumerations are described.

I hope this helps.

Jonathan

Hi Jonathan (@elektrolubach),

thank you for that hint, but I have read this documnent already. My setup consists of TWO inverters (SE4000H as RS485 master and SE2200H as RS485 slave) incl. battery (LG RESU 10H) and one meter (WND-3Y-400-MB).

The registers described in your referenced document are for a single inverter only (and multiple meters). So far as I have seen within this document there are only register addresses for one inverter (the one that is connected to ethernet). The SE2200H communicates its data to SE4000H via RS485, but how can I get this data? And are there registers that represent the sum of both inverters?

Questions over questions
 hopefully you know more about it.

Thank you in advance,
Ralf

The Solaredge doc seems to suggest an external monitor can address each linked inverter independently - you’ve set them all with different Modbus ID numbers. The Solaredge “Leader” appears to able to act as a gateway.

In openHAB terms, set up separate TCP Bridge Things for each inverter, with same IP address and different ID.

Hi @rossko57 ,

sorry but this raises modbus exceptions. Any other ideas?

Based on the comprehensive information supplied, no.

Hi @rossko57 ,

the binding tries to connect with ID=2 but without success: it gives up after 3 times and restarts communication again giving up after 3 times, and so on


I also tried ID=3 with same result. After I checked my inverter settings, the have on RS485 bus the IDs 1 (SE2200H) and 2 (SE4000H). Thus I thought, that i need to use these IDs in the bridge settings, but only ID=1 has success.

Error message from PaperUI:
Status: OFFLINE - CONFIGURATION_ERROR Endpoint ‘ModbusTCPSlaveEndpoint@91e82f[address=192.168.8.225,port=502]’ has conflicting parameters: parameters of this thing (modbus:tcp:bridge ‘SE2200H Bridge’) are different from some other thing’s parameter. Ensure that all endpoints pointing to tcp slave ‘192.168.8.225:502’ have same parameters.

It looks like your suggestion using different IDs for same IP address and port is not allewd to configure.

Works for me. What you can’t have is different timeBetweenTransactionsMillis and so on. I don’t think this part of binding “connection pooling” has changed, but it might have.

I used the follwoing:

Bridge modbus:tcp:SE4000TCP [ host=“192.168.8.225”, port=502, id=1, timeBetweenTransactionsMilli=60, timeBetweenReconnectMillis=0, connectMaxTries=3, reconnectAfterMillis=0, connectTimeoutMillis=5000 ] {

Bridge modbus:tcp:SE2200TCP [ host=“192.168.8.225”, port=502, id=2, timeBetweenTransactionsMilli=60, timeBetweenReconnectMillis=0, connectMaxTries=3, reconnectAfterMillis=0, connectTimeoutMillis=5000 ] {

Any more information required?

Looks sensible to me. Let’s summon a second opinion
 @ssalonen ? This is a valid usage for gateways, has something changed here?

It should be like @rossko57 said above and highlighted in the docs

Note: Advanced parameters must be equal for all tcp things sharing the same host and port.

Please refer the docs to see what are the full set of parameters. Double check your spelling, I see typos above, e.g. There is no “timeBetweenTransactionsMilli” but there is “timeBetweenTransactionsMillis” with s in the end. Bullet proof way is to open the thing configuration in PaperUI and verify the parameters.

Please also note that even one tcp thing with settings off can trigger this error. Check all your things, including the ones created in UI.

sharp eyes there, Sami :microscope:

Hi @rossko57 and @ssalonen

indeed, my fault. But even after fixing this issue I still have trouble with the communication. The brdiges are fine (green) in PaperUI but communication using ID=2 fails (SE4000H thing). What setup do you use for your bridge and thing setup?

Here is my new configuration and the error messages shown:

Bridge modbus:tcp:SE2K "PV Bridge ID1" [ host="192.168.8.225", port=502, id=1, timeBetweenTransactionsMillis=60, timeBetweenReconnectMillis=0, connectMaxTries=3, reconnectAfterMillis=0, connectTimeoutMillis=5000, enableDiscovery=true ]
{
    Thing modbus:inverter-single-phase:bridge:SE2200H "PV SE2200H Wechselrichter" (modbus:tcp:modbusbridge) [ address=40069, length=52, refresh=15, maxTries=3 ]
    Thing modbus:meter-wye-phase:bridge:WattNode "PV WattNode WND-3Y-400-MB Meter" (modbus:tcp:modbusbridge) [ address=40188, length=105, refresh=15, maxTries=3 ]
}

Bridge modbus:tcp:SE4K "PV Bridge ID2" [ host="192.168.8.225", port=502, id=2, timeBetweenTransactionsMillis=60, timeBetweenReconnectMillis=0, connectMaxTries=3, reconnectAfterMillis=0, connectTimeoutMillis=5000, enableDiscovery=true ]
{
    Thing modbus:inverter-single-phase:bridge:SE4000H "PV SE4000H Wechselrichter" (modbus:tcp:modbusbridge) [ address=40069, length=52, refresh=15, maxTries=3 ]
}

Error in PaperUI at SE4000H inverter thing:

Status: OFFLINE - COMMUNICATION_ERROR Error with read: org.openhab.io.transport.modbus.internal.ModbusSlaveIOExceptionImpl: Modbus IO Error with cause=ModbusIOException, EOF=false, message='I/O exception: SocketTimeoutException Read timed out', cause2=null

Error in log:

2021-02-14 11:49:28.806 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Try 1 out of 3 failed when executing request (ModbusReadRequestBlueprint@a64f77[slaveId=2,functionCode=READ_MULTIPLE_REGISTERS,start=40069,length=52,maxTries=3]). Will try again soon. Error was I/O error, so reseting the connection. Error details: net.wimpi.modbus.ModbusIOException I/O exception: SocketTimeoutException Read timed out [operation ID 1cd2ce76-19e2-4e94-b3e9-352c72a75528]
2021-02-14 11:49:32.035 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Try 2 out of 3 failed when executing request (ModbusReadRequestBlueprint@a64f77[slaveId=2,functionCode=READ_MULTIPLE_REGISTERS,start=40069,length=52,maxTries=3]). Will try again soon. Error was I/O error, so reseting the connection. Error details: net.wimpi.modbus.ModbusIOException I/O exception: SocketTimeoutException Read timed out [operation ID 1cd2ce76-19e2-4e94-b3e9-352c72a75528]
2021-02-14 11:49:35.343 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Last try 3 failed when executing request (ModbusReadRequestBlueprint@a64f77[slaveId=2,functionCode=READ_MULTIPLE_REGISTERS,start=40069,length=52,maxTries=3]). Aborting. Error was I/O error, so reseting the connection. Error details: net.wimpi.modbus.ModbusIOException I/O exception: SocketTimeoutException Read timed out [operation ID 1cd2ce76-19e2-4e94-b3e9-352c72a75528]

Uhh, both bridge Things have the typo now. I think that will just get ignored.

You are trying to manually configure the sunspec extension? Think I’d let it auto discover.

Where have you seen this typo? It’s correctly written as described in the documentation. However, I also tried autodiscovery without success. Only the SE4000H the WND-3Y-400-MB is found. Nothing more. Potentially it is a SunSpec limitation.

There is no timeBetweenTransactionsMilli= , it should have s at the end.
As said, this will do no harm and just be ignored, instead taking the default values which is 60 anyway.

Okay, I do not think trying to manually force the same config to work will help.
I think you have to enable the Sunspec feature in each box.

In your first post, you said you had the SE4000H working successfully, apparently using @elektrolubach “generic” Modbus-TCP setup.
Have you removed that now?

Yes, I switched to sunspec due to simpler configuration and much more overview in PaperUI (each register is shown as Thing using “generic” modbus configuration).