Photovoltaik mit Eigenverbrauch Steuerung (Kostal plenticore; EM410)

Begonnen von ch.eick, 16 Juli 2019, 19:18:12

Vorheriges Thema - Nächstes Thema

ch.eick

Update 2020.08.27 - Es wurde nun eine Wiki Seite begonnen Kostal Plenticore 10 Plus
Update 2020.06.18 - Raw Definition von LWP_PV DOIF aktualisiert
Update 2020.06.15 - Raw Definition von PV_Anlage_1 aktualisiert
Update 2020.05.27 - Raw Definition von Pool und Waschmaschine aktualisiert. Der Pool wird auch bei 70% Einspeisung sofort aktiviert
Update 2020.02.11 - Raw Definitionen aktualisiert und Shelly1 ergaenzt; Pool und Waschmaschine im Thread ergaenzt; Viel Feintuning bei den Geraeten
Update 2020.01.11 - Es hat sich einiges in den Devices getan. Manuelles Ein/Aus; Status Erkennung der geschalteten Geräte anhand des Stromverbrauchs; Endabschaltung, wenn kein Strom mehr benoetigt wird; Formatierung der Devices fuer FhemWeb;
Update 2019.08.14 - Raw Definitionen aktualisiert und Shelly device ergänzt
Update 2019.07.17 - Raw Definitionen teilweise aktualisiert

Hallo zusammen.

Der Ein oder Andere hat es bereit rausgelesen, dass ich eine Photovoltaik Anlage plane betreibe.
Auf Grund der 70% Regelung möchte ich natürlich den Strom erstmal selber verbrauchen.

Die Anlage meiner Wahl ist ein Kostal Plenticore mit BYD Pufferspeicher und einem EM410/KSEM.
Nach Studium der Dokumentation aller Geräte und Erweiterung meiner Suche zu SMA Sunny Home Manager 2.0 habe ich es entweder nicht vollständig verstanden oder noch nicht herausgefunden, wie man die Eigensteuerung für den Verbrauch konfiguriert.

- Bei SMA soll es in Verbindung mit dem Portal für bis zu 5 Geräte gehen.
- In Verbindung mit SMA benötigt man dann wohl auch spezielle Aktoren, mit denen man dann die Steckdose schaltet.
- Beim Kostal Plenticore habe ich nur eine Möglichkeit gefunden, die mir ein Signal über ein potentialfreies Relais liefert. Dieses Relais hat bei mir keine Verwendung.

- Und was ist mit meinem SmartHome :-) ?

Okay, das war die Einleitung und nun bin ich mal los gelaufen und habe mir anhand der Entscheidungsparameter etwas eigenes gebaut.

1. Eine Novelan Wärmepumpe mit Luxtronik2 und einem Photovoltaik Input Port gilt es anzusteuern.

1.1 Der SWTin Port zeigt den Status des Ports an, wenn man den Photovoltaik Modus über die Steuerung aktiviert hat.
    Hier der Code, um den Port dann auch im FHEM zu sehen.

defmod Heizung LUXTRONIK2 <IP-Adresse> 600
attr Heizung alias Heizung
attr Heizung allowSetParameter 1
attr Heizung doStatistics 0
attr Heizung ignoreFirmwareCheck 1
attr Heizung room Heizung->System

attr Heizung userHeatpumpValues 36 SWTin

attr Heizung verbose 0


1.2 Dieser SWTin Port wird mit einem Shelly1 Aktor bedient
   220V auf dem SWTin Port aktiviert den Photovoltaik Modus.

2. Test Umgebung
   Um bereits beginnen zu können habe ich Dummy, FileLog, readingsGroup, SVG, HourCounter und DOIF bemüht.

2.1 Die Anforderung (Das ist noch von vor der Inbetriebnahme und dient nur noch zur Erinnerung an die Anfaenge)

- Eine Wärmepumpe sollte nicht ständig ein und aus geschaltet werden. Hier hoffe ich, dass der Hersteller sich da auch Gedanken gemacht hat. Nach langer Beobachtung des Stromzählers (SMA Energy Meter 20) weiß ich nun wie lang die Pumpe durchlaufen sollte und wie hoch der Stromverbrauch ist, um das Werk zu vollbringen.

- Einmal eingeschaltet sollte die LWP mindestens ein Zeitfenster von 1 Stunde bekommen
- Damit genügend PV Strom da ist sollte der Leistungsüberschuss mindestens 3500 Watt sein. Sollte etwas mehr benötigt werden, dann leg ich halt etwas drauf.
- Fällt der PV Strom unter 3000 Watt wird nach ablauf der Mindestlaufzeit (zum Geräteschutz) das SWTin Signal wieder weg genommen.

- Liefert der Wechselrichter (WR) mehr als die besagten 3500 Watt wird nochmals 15 Minuten gewartet, damit es auch stabiel ist und nicht nur ein kurzer Peak.
- Ansonsten stopt das DOIF den wait timer wieder und es geht von vorne los.
- In der Novelan LWP habe ich bisher Sterrzeiten eingerichtet, damit das Brauchwasser erst ab 14:00 Uhr zur höchsten Außentemperatur bereitet wird.
- Mit der PV Anlage möchte ich das Brauchwasser bereits vorher auf die Maximal mögliche Temperatur anheben. Die Sperrzeiten werden dann auf 16:00 Uhr verschoben, falls die PV Anlage es nicht geschafft hat.

- Ist die Mindestlaufzeit abgelaufen und die PV Leistung reicht nicht mehr, wird das SWTin Signal wieder abgeschaltet.

- Dann gibt es noch eine maximale Laufzeit pro Tag, die ich auf 4 Stunden festgelegt habe. Danach sollte der Wärmepuffer gefüllt sein.
   Generell steuert die LWP ihre Einschaltzyklen auch im PV Modus automatisch selber und startet nur wenn die Hysteresewerte unterschritten werden.
   Das SWTin Signal sagt nur, es steht Überschussleistung zur Verfühgung und das Signal hebt die Heizungskurve sowie die Brauchwassertemperatur an.

Und nun die fhem Umsetzung mit den Updates (s.o.):

1. Ein Zähler für die Laufzeiten der LWP (jedes Geraet hat einen eigenen, die jedoch nicht alle hier gelistet sind)

defmod LWP_Counter HourCounter LWP:on.* LWP:off
attr LWP_Counter alias LWP_Counter
attr LWP_Counter event-min-interval .*:600
attr LWP_Counter event-on-change-reading .*
attr LWP_Counter group PV Eigenverbrauch-Steuerung
attr LWP_Counter icon time_timer
attr LWP_Counter interval 5
attr LWP_Counter room Strom->Photovoltaik
attr LWP_Counter sortby 03
attr LWP_Counter verbose 0


2. Das Dummy, das die LWP darstellt und die Parameter bereit hält

defmod LWP dummy
attr LWP alias LWP_LuftWärmePumpe
attr LWP group PV Eigenverbrauch
attr LWP icon sani_earth_source_heat_pump
attr LWP readingList LWP_Button PowerLevelMinTime PowerLimitOn PowerLimitOff RunTimeMin RunTimePerDay SetCmdOff SetCmdOn TimeStart TimeEnd
attr LWP room Strom->Photovoltaik
attr LWP setList LWP_Button:uzsuToggle,on,off PowerLevelMinTime:slider,60,30,300 PowerLimitOn:slider,1000,250,4000 PowerLimitOff:slider,1000,250,4000 RunTimeMin:slider,300,300,7200 RunTimePerDay:slider,900,300,28800 SetCmdOff SetCmdOn TimeStart:time TimeEnd:time
attr LWP sortby 03
attr LWP stateFormat state
attr LWP verbose 0
attr LWP webCmd LWP_Button

# Hier noch einige Basiswerte, die bei der ersten Konfiguration gesetzt werden muessen
setreading LWP LWP_Button off
setreading LWP SetCmdOff set shelly01 off 0
setreading LWP SetCmdOn set shelly01 on 0
setreading LWP PowerLevelMinTime 600
setreading LWP PowerLimitOff 2250
setreading LWP PowerLimitOn 2750
setreading LWP RunTimeMin 3600
setreading LWP RunTimePerDay 28800
setreading LWP TimeEnd 16:00
setreading LWP TimeStart 08:00


3. Mein Kostal Plenticore 10 Plus mit BYD Batterie
Die Kommunikation ist ueber ModBus TCP implementiert. Der Wechselrichter liefert ebenfalls Daten zur Batterie und zur KSEM / EM410 (SmartMeter).


defmod PV_Anlage_1 ModbusAttr 71 60 192.168.178.18:1502 TCP

attr PV_Anlage_1 DbLogExclude .*
attr PV_Anlage_1 DbLogInclude Act_state_of_charge,Actual_battery_charge_-minus_or_discharge_-plus_Power,Actual_battery_charge_usable_Power,Battery_temperature,Home_own_consumption_from_PV,Home_own_consumption_from_battery,Home_own_consumption_from_grid,Inverter_state,Power_DC1,Power_DC2,Power_DC_Sum,Total_DC_Power,Total_DC_Power_Max,Total_PV_Power_reserve,Voltage_DC1,Voltage_DC2,.*_yield,Solar_.*,Statistic_.*
attr PV_Anlage_1 alias PV_Einspeisung
attr PV_Anlage_1 comment Kostal Plenticore 10 Plus mit BYD Speicher
attr PV_Anlage_1 dev-h-defFormat %.2f
attr PV_Anlage_1 dev-h-defLen 2
attr PV_Anlage_1 dev-h-defPoll 1
attr PV_Anlage_1 dev-h-defRevRegs 1
attr PV_Anlage_1 dev-h-defUnpack f>
attr PV_Anlage_1 dev-type-STR-format %s
attr PV_Anlage_1 dev-type-STR-len 8
attr PV_Anlage_1 dev-type-STR-revRegs 0
attr PV_Anlage_1 dev-type-STR-unpack a*
attr PV_Anlage_1 event-on-change-reading statistics_.*,Statistic_.*,Act_state_of_charge,Actual_battery_charge_.*,Battery_temperature,Home_own_consumption_from_.*,Inverter_state,Power_DC1,Power_DC2,Power_DC_Sum,Total_DC_Power,Total_DC_Power_Max,Total_PV_Power_reserve,Voltage_DC1,Voltage_DC2,.*_yield,Solar_.*
attr PV_Anlage_1 group PV Eigenverbrauch
attr PV_Anlage_1 icon sani_solar
attr PV_Anlage_1 obj-h100-reading Total_DC_Power
attr PV_Anlage_1 obj-h104-format %s
attr PV_Anlage_1 obj-h104-reading State_of_energy_manager
attr PV_Anlage_1 obj-h104-revRegs 0
attr PV_Anlage_1 obj-h104-unpack N
attr PV_Anlage_1 obj-h106-reading Home_own_consumption_from_battery
attr PV_Anlage_1 obj-h108-reading Home_own_consumption_from_grid
attr PV_Anlage_1 obj-h110-reading Total_home_consumption_Battery
attr PV_Anlage_1 obj-h112-reading Total_home_consumption_Grid
attr PV_Anlage_1 obj-h114-reading Total_home_consumption_PV
attr PV_Anlage_1 obj-h116-reading Home_own_consumption_from_PV
attr PV_Anlage_1 obj-h118-reading Total_home_consumption
attr PV_Anlage_1 obj-h120-reading Isolation_resistance
attr PV_Anlage_1 obj-h122-reading Power_limit_from_EVU
attr PV_Anlage_1 obj-h124-reading Total_home_consumption_rate
attr PV_Anlage_1 obj-h14-reading Inverter_serial_number
attr PV_Anlage_1 obj-h14-type STR
attr PV_Anlage_1 obj-h144-reading Worktime
attr PV_Anlage_1 obj-h150-reading Actual_cos_phi
attr PV_Anlage_1 obj-h152-reading Grid_frequency
attr PV_Anlage_1 obj-h154-reading Current_Phase_1
attr PV_Anlage_1 obj-h156-reading Active_power_Phase_1
attr PV_Anlage_1 obj-h158-reading Voltage_Phase_1
attr PV_Anlage_1 obj-h160-reading Current_Phase_2
attr PV_Anlage_1 obj-h162-reading Active_power_Phase_2
attr PV_Anlage_1 obj-h164-reading Voltage_Phase_2
attr PV_Anlage_1 obj-h166-reading Current_Phase_3
attr PV_Anlage_1 obj-h168-reading Active_power_Phase_3
attr PV_Anlage_1 obj-h170-reading Voltage_Phase_3
attr PV_Anlage_1 obj-h172-reading Total_AC_active_power
attr PV_Anlage_1 obj-h174-reading Total_AC_reactive_power
attr PV_Anlage_1 obj-h178-reading Total_AC_apparent_power
attr PV_Anlage_1 obj-h190-reading Battery_charge_current
attr PV_Anlage_1 obj-h194-format %.0f
attr PV_Anlage_1 obj-h194-reading Number_of_battery_cycles
attr PV_Anlage_1 obj-h200-reading Actual_battery_charge_-minus_or_discharge_-plus_current
attr PV_Anlage_1 obj-h202-reading PSSB_fuse_state
attr PV_Anlage_1 obj-h208-format %.0f
attr PV_Anlage_1 obj-h208-reading Battery_ready_flag
attr PV_Anlage_1 obj-h210-reading Act_state_of_charge
attr PV_Anlage_1 obj-h212-reading Battery_state
attr PV_Anlage_1 obj-h214-reading Battery_temperature
attr PV_Anlage_1 obj-h216-reading Battery_voltage
attr PV_Anlage_1 obj-h218-reading Cos_phi_(powermeter)
attr PV_Anlage_1 obj-h220-reading Frequency_(powermeter)
attr PV_Anlage_1 obj-h222-reading Current_phase_1_(powermeter)
attr PV_Anlage_1 obj-h224-reading Active_power_phase_1_(powermeter)
attr PV_Anlage_1 obj-h226-reading Reactive_power_phase_1_(powermeter)
attr PV_Anlage_1 obj-h228-reading Apparent_power_phase_1_(powermeter)
attr PV_Anlage_1 obj-h230-reading Voltage_phase_1_(powermeter)
attr PV_Anlage_1 obj-h232-reading Current_phase_2_(powermeter)
attr PV_Anlage_1 obj-h234-reading Active_power_phase_2_(powermeter)
attr PV_Anlage_1 obj-h236-reading Reactive_power_phase_2_(powermeter)
attr PV_Anlage_1 obj-h238-reading Apparent_power_phase_2_(powermeter)
attr PV_Anlage_1 obj-h240-reading Voltage_phase_2_(powermeter)
attr PV_Anlage_1 obj-h242-reading Current_phase_3_(powermeter)
attr PV_Anlage_1 obj-h244-reading Active_power_phase_3_(powermeter)
attr PV_Anlage_1 obj-h246-reading Reactive_power_phase_3_(powermeter)
attr PV_Anlage_1 obj-h248-reading Apparent_power_phase_3_(powermeter)
attr PV_Anlage_1 obj-h250-reading Voltage_phase_3_(powermeter)
attr PV_Anlage_1 obj-h252-reading Total_active_power_(powermeter)
attr PV_Anlage_1 obj-h254-reading Total_reactive_power_(powermeter)
attr PV_Anlage_1 obj-h256-reading Total_apparent_power_(powermeter)
attr PV_Anlage_1 obj-h258-reading Current_DC1
attr PV_Anlage_1 obj-h260-reading Power_DC1
attr PV_Anlage_1 obj-h266-reading Voltage_DC1
attr PV_Anlage_1 obj-h268-reading Current_DC2
attr PV_Anlage_1 obj-h270-reading Power_DC2
attr PV_Anlage_1 obj-h276-reading Voltage_DC2
attr PV_Anlage_1 obj-h278-reading Current_DC3
attr PV_Anlage_1 obj-h280-reading Power_DC3
attr PV_Anlage_1 obj-h286-reading Voltage_DC3
attr PV_Anlage_1 obj-h320-reading Total_yield
attr PV_Anlage_1 obj-h322-reading Daily_yield
attr PV_Anlage_1 obj-h324-reading Yearly_yield
attr PV_Anlage_1 obj-h326-reading Monthly_yield
attr PV_Anlage_1 obj-h38-reading Software-Version_Maincontroller_(MC)
attr PV_Anlage_1 obj-h38-type STR
attr PV_Anlage_1 obj-h384-len 16
attr PV_Anlage_1 obj-h384-reading Inverter_network_name
attr PV_Anlage_1 obj-h384-type STR
attr PV_Anlage_1 obj-h420-reading IP-address
attr PV_Anlage_1 obj-h420-type STR
attr PV_Anlage_1 obj-h428-reading IP-subnetmask
attr PV_Anlage_1 obj-h428-type STR
attr PV_Anlage_1 obj-h436-reading IP-gateway
attr PV_Anlage_1 obj-h436-type STR
attr PV_Anlage_1 obj-h446-reading IP-DNS1
attr PV_Anlage_1 obj-h446-type STR
attr PV_Anlage_1 obj-h454-reading IP-DNS2
attr PV_Anlage_1 obj-h454-type STR
attr PV_Anlage_1 obj-h46-reading Software-Version_IO-Controller_(IOC)
attr PV_Anlage_1 obj-h46-type STR
attr PV_Anlage_1 obj-h514-len 1
attr PV_Anlage_1 obj-h514-reading Battery_actual_SOC
attr PV_Anlage_1 obj-h517-reading Battery_Manufacturer
attr PV_Anlage_1 obj-h517-type STR
attr PV_Anlage_1 obj-h525-format %c
attr PV_Anlage_1 obj-h525-reading Battery_Model_ID
attr PV_Anlage_1 obj-h525-unpack N
attr PV_Anlage_1 obj-h527-format %c
attr PV_Anlage_1 obj-h527-reading Battery_Serial_Number
attr PV_Anlage_1 obj-h529-len 4
attr PV_Anlage_1 obj-h529-reading Work_Capacity
attr PV_Anlage_1 obj-h529-unpack N
attr PV_Anlage_1 obj-h531-format %.0f
attr PV_Anlage_1 obj-h531-reading Inverter_Max_Power
attr PV_Anlage_1 obj-h531-unpack N
attr PV_Anlage_1 obj-h535-revRegs 0
attr PV_Anlage_1 obj-h535-unpack n
attr PV_Anlage_1 obj-h551-revRegs 0
attr PV_Anlage_1 obj-h559-revRegs 0
attr PV_Anlage_1 obj-h56-format %.0f
attr PV_Anlage_1 obj-h56-reading Inverter_state
attr PV_Anlage_1 obj-h56-unpack N
attr PV_Anlage_1 obj-h575-len 1
attr PV_Anlage_1 obj-h575-reading Inverter_Generation_Power_(actual)
attr PV_Anlage_1 obj-h577-len 2
attr PV_Anlage_1 obj-h577-reading Generation_Energy
attr PV_Anlage_1 obj-h577-unpack N
attr PV_Anlage_1 obj-h578-reading Total_energy
attr PV_Anlage_1 obj-h582-reading Actual_battery_charge-discharge_power
attr PV_Anlage_1 obj-h586-format %s
attr PV_Anlage_1 obj-h586-reading Battery_Firmware
attr PV_Anlage_1 obj-h586-unpack N
attr PV_Anlage_1 obj-h588-format %s
attr PV_Anlage_1 obj-h588-len 1
attr PV_Anlage_1 obj-h588-reading Battery_Type
attr PV_Anlage_1 obj-h588-unpack N
attr PV_Anlage_1 obj-h6-reading Inverter_article_number
attr PV_Anlage_1 obj-h6-type STR
attr PV_Anlage_1 obj-h768-len 32
attr PV_Anlage_1 obj-h768-reading Productname
attr PV_Anlage_1 obj-h768-type STR
attr PV_Anlage_1 obj-h800-len 32
attr PV_Anlage_1 obj-h800-reading Power_class
attr PV_Anlage_1 obj-h800-type STR
attr PV_Anlage_1 room Strom->Photovoltaik
attr PV_Anlage_1 sortby 01
attr PV_Anlage_1 stateFormat {sprintf("\
<TABLE>\
\
<TR>\
  <TH ALIGN=\"MIDDLE\" WIDTH=\"20\">Batterie %s</TH>\
  <TH ALIGN=\"MIDDLE\" WIDTH=\"20\">aktuell</TH>\
  <TH ALIGN=\"RIGHT\" WIDTH=\"20\">Hausverbrauch</TH>\
  <TH ALIGN=\"MIDDLE\" WIDTH=\"20\">Erträge</TH>\
</TR>\
\
<TR>\
  <TD ALIGN=\"MIDDLE\" WIDTH=\"20\">\
    Leistung:  %04d W<br>\
    Temp.: %02.1f °C<br>\
    Ladung total: %2d %%<br>\
    Ladung Res.: %04d Wh\
  </TD>\
\
  <TD ALIGN=\"RIGHT\" WIDTH=\"20\">\
    DC total: %05d W<br>\
    <br>\
    <br>\
    PV reserve: %05d W\
  </TD>\
\
  <TD ALIGN=\"RIGHT\" WIDTH=\"20\">\
    von PV: %05d W <br>\
    von Batterie: %05d W<br>\
    vom Netz: %05d W<br>\
    ins Haus: %05d W<br>\
    Netz: %05d W\
  </TD>\
\
  <TD ALIGN=\"RIGHT\" WIDTH=\"20\">\
    Tag: %05d KWh <br>\
    Monat: %05d KWh<br>\
    Jahr: %05d KWh<br>\
    Total: %05d KWh\
  </TD>\
</TR>\
\
</TABLE>\
" , \
(ReadingsVal($name,"Actual_battery_charge_-minus_or_discharge_-plus_Power",0) lt 0) ? "<span style='color:#00FF00'>Laden</span>":"<span style='color:#FF0000'>Entladen</span>" ,\
\
ReadingsVal($name,"Actual_battery_charge_-minus_or_discharge_-plus_Power",0),\
ReadingsVal($name,"Battery_temperature",0) ,\
ReadingsVal($name,"Act_state_of_charge",0) ,\
ReadingsVal($name,"Actual_battery_charge_usable_Power",0) ,\
\
ReadingsVal($name,"Power_DC_Sum","0"),\
ReadingsVal($name,"Total_PV_Power_reserve","0"),\
\
ReadingsVal($name,"Home_own_consumption_from_PV",0) ,\
ReadingsVal($name,"Home_own_consumption_from_battery",0) ,\
ReadingsVal($name,"Home_own_consumption_from_grid",0),\
ReadingsVal($name,"Home_own_consumption_from_PV",0) +ReadingsVal($name,"Home_own_consumption_from_battery",0)+ReadingsVal($name,"Home_own_consumption_from_grid",0),\
ReadingsVal($name,"Total_active_power_(powermeter)",0),\
\
round(ReadingsVal($name,"Daily_yield",0)/1000 ,0),\
round(ReadingsVal($name,"Monthly_yield",0)/1000 ,0) ,\
round(ReadingsVal($name,"Yearly_yield",0)/1000 ,0) ,\
round(ReadingsVal($name,"Total_yield",0)/1000 ,0)\
)}
attr PV_Anlage_1 userReadings Power_DC_Sum:Total_DC_Power.* { ReadingsVal($NAME,"Power_DC1","0")+ReadingsVal($NAME,"Power_DC2","0") },\
\
Total_PV_Power_reserve:Total_DC_Power.* {my $reserve = ReadingsVal($NAME,"Power_DC_Sum","0") * 0.90 - ReadingsVal($NAME,"Home_own_consumption_from_PV","0");;;; ($reserve lt 0)?0:round($reserve,3)  },\
\
Total_DC_Power_Max:Total_DC_Power.* { my $Bat_out = (ReadingsVal($NAME,"Actual_battery_charge_-minus_or_discharge_-plus_current","0")*ReadingsVal($NAME,"Battery_voltage","0"));;;; ($Bat_out gt 0)?ReadingsVal($NAME,"Power_DC_Sum","0") + $Bat_out :ReadingsVal($NAME,"Power_DC_Sum","0") },\
\
Actual_battery_charge_-minus_or_discharge_-plus_Power:Actual_battery_charge_-minus_or_discharge_-plus_current.* {round((ReadingsVal($NAME,"Actual_battery_charge_-minus_or_discharge_-plus_current","0")*ReadingsVal($NAME,"Battery_voltage","0")),0)},\
\
Actual_battery_charge_usable_Power:Act_state_of_charge.* {my $x = (8960*(ReadingsVal($NAME,"Act_state_of_charge","0")-10)/100);;;; ($x lt 0)?0:round($x,0) },\
\
Solar_SolarRadiation:Total_DC_Power.* { ReadingsVal("wetter_wolfskehlen_II","solarRadiation",0) },\
Solar_Correction_Temp:Total_DC_Power.* { my $tempk = -0.39 ;;;; my $temp = ReadingsVal("Heizung","heatSourceIN",0)+10;;;; my $x =  round((1 + ( $temp - 25) * $tempk / 100),3) },\
Solar_East:Total_DC_Power.* { my $x = 13 * 0.310 * ReadingsVal("$NAME","Solar_SolarRadiation",0) * ReadingsVal("$NAME","Solar_Correction_Temp",0) * ReadingsVal("$NAME","Solar_Correction_Factor",0) * Solar_plain(40,-90);;;; ($x lt 0)?0:round($x,0) },\
Solar_South:Total_DC_Power.* { my $x = 6 * 0.310 * ReadingsVal("$NAME","Solar_SolarRadiation",0) * ReadingsVal("$NAME","Solar_Correction_Temp",0) * ReadingsVal("$NAME","Solar_Correction_Factor",0) * Solar_plain(40,0);;;; ($x lt 0)?0:round($x,0) },\
Solar_West:Total_DC_Power.* { my $x = 13 * 0.310 * ReadingsVal("$NAME","Solar_SolarRadiation",0) * ReadingsVal("$NAME","Solar_Correction_Temp",0) * ReadingsVal("$NAME","Solar_Correction_Factor",0) * Solar_plain(40,+90);;;; ($x lt 0)?0:round($x,0) },\
\
Solar_Calculation:Total_DC_Power.* { round( ( ReadingsVal($NAME,"Solar_East",0) + ReadingsVal($NAME,"Solar_South",0) + ReadingsVal($NAME,"Solar_West",0) ) ,0) },\
\
statistics_clean:statistics_output.* { my $x =  ReadingsVal($NAME,"statistics_output",0);;;; $x =~ s/\{"moduleid": "scb:statistic:EnergyFlow", "processdata": \[|id": "|, "unit": "", "value"|^\[|\]\}\]$//g;;;; $x =~ s/moduleid/statistics_00_moduleid/g;;;; $x =~ s/processdata/statistics/g;;;; $x =~ s/\}\, \{/\, /g;;;; return $x }
attr PV_Anlage_1 verbose 0

setstate PV_Anlage_1 \
<TABLE>\
\
<TR>\
  <TH ALIGN="MIDDLE" WIDTH="20">Batterie <span style='color:#FF0000'>Entladen</span></TH>\
  <TH ALIGN="MIDDLE" WIDTH="20">aktuell</TH>\
  <TH ALIGN="RIGHT" WIDTH="20">Hausverbrauch</TH>\
  <TH ALIGN="MIDDLE" WIDTH="20">Erträge</TH>\
</TR>\
\
<TR>\
  <TD ALIGN="MIDDLE" WIDTH="20">\
    Leistung:  0713 W<br>\
    Temp.: 27.3 °C<br>\
    Ladung total: 84 %<br>\
    Ladung Res.: 6630 Wh\
  </TD>\
\
  <TD ALIGN="RIGHT" WIDTH="20">\
    DC total: 00973 W<br>\
    <br>\
    <br>\
    PV reserve: 00000 W\
  </TD>\
\
  <TD ALIGN="RIGHT" WIDTH="20">\
    von PV: 00912 W <br>\
    von Batterie: 00672 W<br>\
    vom Netz: 00000 W<br>\
    ins Haus: 01585 W<br>\
    Netz: 00007 W\
  </TD>\
\
  <TD ALIGN="RIGHT" WIDTH="20">\
    Tag: 00015 KWh <br>\
    Monat: 00608 KWh<br>\
    Jahr: 04841 KWh<br>\
    Total: 05290 KWh\
  </TD>\
</TR>\
\
</TABLE>\


4. Nun endlich das DOIF, in dem die Logik steckt. Einige Parameter und Konfigurationswerte sind im LWP Dummy unter gebracht, damit man nicht direkt ans DOIF muss.
    Dies ist der Stand von 2020.06.18:
     - Es hat sich ergeben, dass der PV-Modus im Fruehling und Sommer nicht wirklich benoetigt wird. Dafuer gibt es jetzt cmd_nr "10 Hohe Priorität im Winter fuer die LWP"
     - Nach einem manuellen PV-Modus, z.B. am WE wenn Besuch da ist, wird der LWP_Button wieder auf off gesetzt
     - Auch neu ist cmd_nr "9 LWP Zwangseinschalten" . Sollte das Brauchwasser noch nicht aufgeheizt sein, wird um die Hysterese erhöht.
       Dies kann passieren, wenn am Tag vorher der PV-Modus lief und dann das Wasser noch knapp über dem Mindestwert ist.
    Das rauf/runter setzen der Brauchwassersolltemperatur ist notwendig, weil der PV-Modus nicht so laeuft, wie er sollte ;-)
    Novelan ist das bekannt, sie werden es aber nicht in der Luxtronik 2.0 korrigieren.

defmod LWP_PV DOIF ################################################################################################################\
## 1 Eigenverbrauch abschalten: wenn Mindestlaufzeit erreicht wurde und Maximallaufzeit pro Tag erreicht ist\
##\
    ([LWP_Counter:pulseTimePerDay] >= [LWP:RunTimePerDay] and\
     [LWP_Counter:pulseTimeIncrement] >= [LWP:RunTimeMin] and\
     [LWP:state] ne "off" and [LWP:LWP_Button] eq "off" )\
\
    ({Log 3, " LWP_PV cmd_1 PV : LWP off"}\
     {fhem("".ReadingsVal("LWP","SetCmdOff",0))}\
     {fhem("set LWP off")}\
     {fhem("set Heizung hotWaterTemperatureTarget 50.0")}\
    )\
################################################################################################################\
## 2 Eigenverbrauch abschalten: wenn Mindestlaufzeit erreicht wurde und die PV Produktion unter dem Mindestbedarf ist\
##\
DOELSEIF\
  ( ([PV_Anlage_1:Total_PV_Power_reserve]+[StromZaehler_Heizung:SMAEM1901401955_Bezug_Wirkleistung]) < [LWP:PowerLimitOff] and\
     [LWP_Counter:pulseTimeIncrement] >= [LWP:RunTimeMin] and\
     [LWP:state] ne "off" and\
     [LWP:LWP_Button] ne "on" )\
\
    ({Log 3, " LWP_PV cmd_2 PV : LWP off"}\
     {fhem("".ReadingsVal("LWP","SetCmdOff",0))}\
     {fhem("set LWP off")}\
     {fhem("set Heizung hotWaterTemperatureTarget 50.0")}\
    )\
################################################################################################################\
## 3 Stop, wenn es nur ein kurzer peak ist. Dieser Do Zweig setzt den wait timer vom Einschaltkommando cmd_4 wieder außerkraft,\
##   wenn wärend der Wartezeit die PV Anlage zuwenig liefert.\
##\
DOELSEIF\
    ([PV_Anlage_1:Total_PV_Power_reserve] < [LWP:PowerLimitOff] and\
     [LWP_PV:wait_timer] ne "no timer" and\
     [LWP_PV:wait_timer] ne "" and\
     [LWP:state] eq "off" )\
\
    ({Log 3, "LWP_PV cmd_3 PV : Stop wait timer LWP"})\
################################################################################################################\
## 4 Eigenverbrauch einschalten: wenn PV Produktion über dem Mindestbedarf ist und die Laufzeit pro Tag noch nicht erreicht ist\
##\
DOELSEIF\
    ([Astro:ObsSeason] ne "Sommer" and [Astro:ObsSeason] ne "Frühling" and\
     [PV_Anlage_1:Total_PV_Power_reserve] >= [LWP:PowerLimitOn] and\
     [[LWP:TimeStart]-[LWP:TimeEnd]] and\
     [LWP:state] eq "off" and\
     [LWP_Counter:pulseTimePerDay] < [LWP:RunTimePerDay] and\
     [Heizung:hotWaterTemperature] < 60 )\
\
    ({Log 3, "LWP_PV cmd_4 : LWP on"}\
     {fhem("".ReadingsVal("LWP","SetCmdOn",0))}\
     {fhem("set LWP on")}\
     {fhem("set Heizung hotWaterTemperatureTarget 60.0")}\
    )\
################################################################################################################\
## 5 Signal für den PV-Modus der LWP einschalten.\
##\
DOELSEIF\
    ([LWP:LWP_Button] eq "on" )\
\
    ({Log 3, "LWP_PV cmd_5 PV : LWP on for manuel PV-Modus"}\
     {fhem("".ReadingsVal("LWP","SetCmdOn",0))}\
     {fhem("set LWP on")}\
     {fhem("set Heizung hotWaterTemperatureTarget 60.0")}\
     )\
################################################################################################################\
## 6 Signal für den PV-Modus der LWP abschalten.\
##\
DOELSEIF\
    ([LWP:LWP_Button] eq "off" and\
     [$SELF:cmd_nr] eq "5"  )\
\
    ({Log 3, "LWP_PV cmd_6 PV : LWP off after manuel PV-Modus"}\
     {fhem("".ReadingsVal("LWP","SetCmdOff",0))}\
     {fhem("set LWP off")}\
     {fhem("set Heizung hotWaterTemperatureTarget 50.0")}\
    )\
################################################################################################################\
## 7 Stop wait Timer für das Abschalten, wenn die LWP beim Starten noch anläuft\
##\
DOELSEIF\
   ([StromZaehler_Heizung:SMAEM1901401955_Bezug_Wirkleistung] > 300 and\
    [Heizung:opStateHeatPump1] eq "Wärmepumpe kommt" and\
    [Heizung:opStateHeatPump3] eq "Pumpenvorlauf" )\
\
     ({Log 3, "LWP_PV cmd_7 : Stop wait timer LWP"})\
################################################################################################################\
## 8 LWP Ende\
##\
DOELSEIF\
   ([StromZaehler_Heizung:SMAEM1901401955_Bezug_Wirkleistung] < 300 and\
    [LWP_Counter:pulseTimeIncrement] >= [LWP:RunTimeMin] and\
    ([Heizung:opStateHeatPump1] ne "Wärmepumpe läuft" or [Heizung:opStateHeatPump3] eq "Luftabtauen" ) and\
    ([$SELF:cmd_nr] eq "4" or [$SELF:cmd_nr] eq "5" or [$SELF:cmd_nr] eq "10") )\
\
    ({Log 3, "LWP_PV cmd_8 : LWP run finished"}\
     {fhem("".ReadingsVal("LWP","SetCmdOff",0))}\
     {fhem("set LWP off")}\
     {fhem("set Heizung hotWaterTemperatureTarget 50.0")}\
     {fhem("setreading LWP LWP_Button off")}\
    )\
################################################################################################################\
## 9 LWP Zwangseinschalten: Sollte das Brauchwasser noch nicht aufgeheizt sein, wird um die Hysterese erhöht.\
##   Dies kann passieren, wenn am Tag vorher der PV-Modus lief und dann das Wasser noch knapp über dem Mindestwert ist.\
##\
DOELSEIF\
   ([Astro:ObsSeason] ne "Sommer" and [Astro:ObsSeason] ne "Frühling" and\
    [[LWP:TimeEnd]] and\
    [Heizung:hotWaterTemperature] < 47 and\
    ([LWP_Counter:pulseTimePerDay] < [Pool:RunTimePerDay] or\
     [LWP_Counter:countsPerDay] eq 0) )\
\
    ({Log 3, "LWP_PV cmd_9 : LWP on for water heating"}\
\
     {fhem("set Heizung hotWaterTemperatureTarget ". (ReadingsVal("Heizung","hotWaterTemperature",46)+4))}\
\
     {Log 3, "LWP_PV cmd_9 : LWP hotWaterTemperatureTarget ".ReadingsVal("Heizung","hotWaterTemperatureTarget",0)}\
    )\
################################################################################################################\
## 10 Hohe Priorität im Winter fuer die LWP\
##    Einschalten, wenn der Pool läuft, der Speicher geladen ist und noch Überschuss da ist.\
##\
DOELSEIF\
    ([Astro:ObsSeason] eq "Winter" and\
     [PV_Anlage_1:Total_PV_Power_reserve] >= 2000 and\
     [shelly02:power_0] > 800 and\
     [PV_Anlage_1:Act_state_of_charge] > 60 and\
     [Heizung:hotWaterTemperature] < 60 and \
     [$SELF:cmd_nr] ne "10" )\
\
    ({Log 3, "LWP_PV cmd_10 : LWP Priorität"}\
     {fhem("set LWP_PV cmd_4")}\
    )\

attr LWP_PV DbLogExclude .*
attr LWP_PV DbLogInclude state,cmd.*,Device,LWP_Status,wait_timer
attr LWP_PV alias LWP_PV
attr LWP_PV cmdState Maximalzeit pro Tag überschritten|Eigenverbrauch aus|Stop wait timer|Eigenverbrauch ein|LWP ein für manuellen PV-Modus|LWP aus nach manuellem PV-Modus|Stop wait timer fuer aus|LWP aus nach PV-Modus|LWP Brauchwasser nachheizen|LWP Priorität
attr LWP_PV do always
attr LWP_PV group PV Eigenverbrauch-Steuerung
attr LWP_PV icon sani_earth_source_heat_pump
attr LWP_PV room Strom->Photovoltaik
attr LWP_PV sortby 01
attr LWP_PV stateFormat state : LWP_Status : Brauchwasser e_Heizung_hotWaterTemperature °C
attr LWP_PV userReadings LWP_Status { ReadingsVal("Heizung","state","") }
attr LWP_PV verbose 5
attr LWP_PV wait 0:10:0:[LWP:PowerLevelMinTime]:0:0:900:0:0



5. Das Logfile mit Werten, die ich bisher benötigt habe.

defmod FileLog_Photovoltaik FileLog ../log/Photovoltaik-%Y-%m.log LWP:state.*|Pool:state.*|Waschmaschine:state.*|Spuelmaschine:state.*|PV_Anlage_1:(Power_DC|Voltage_DC|Total_AC_active_power
|Total_DC_Power|Total_PV_Power_reserve|Home_own_consumption_from|Actual_battery_charge_-minus_or_discharge_-plus_Power|Actual_battery_charge_usable_Power|Battery_temperature|Act_state_of_charge|Inverter_state).*|LWP_PV:state.*|LWP_PV:wait.*|Pool_PV:state.*|Pool_PV:wait.*|Waschmaschine_PV:state.*|Waschmaschine_PV:wait.*|Spuelmaschine_PV:state.*|Spuelmaschine_PV:wait.*|shelly01:(relay|power).*|shelly02:(relay|power)_.*|shelly03:(relay|power).*|shelly04:(relay|power)_.*
attr FileLog_Photovoltaik addStateEvent 1
attr FileLog_Photovoltaik alias Log Eigenverbrauch_Statistik
attr FileLog_Photovoltaik group Logfile
attr FileLog_Photovoltaik logtype text
attr FileLog_Photovoltaik room Strom->Info


6. Mit dieser readingsGroup hat man etwas Überblick und kann auch direkt Werte verändern, damit man nicht immer ins Device springen muss.

defmod rg_LWP_Status readingsGroup <Device>,<Information>,<Wert> LWP:<Status>,state LWP:<PowerLevelMinTime>,PowerLevelMinTime LWP:<PowerLimitOn>,PowerLimitOn LWP:<PowerLimitOff>,PowerLimitOff LWP:<TimeStart>,!TimeStart LWP:<TimeEnd>,!TimeEnd LWP:<RunTimeMin>,RunTimeMin LWP_Counter:<RunTimeMin>,pulseTimeIncrement LWP:<RunTimePerDay>,RunTimePerDay LWP_Counter:<RunTimePerDay>,pulseTimePerDay LWP_PV:<wait>,wait_timer LWP_PV:<TimeStart>,timer_01_c04 LWP_PV:<TimeEnd>,timer_02_c04
attr rg_LWP_Status alias Status LuftWärmePumpe Eigenverbrauch
attr rg_LWP_Status commands {state  => 'state:on,off',\
PowerLevelMinTime => 'PowerLevelMinTime:selectnumbers,60,60,600,0,lin',\
PowerLimitOn => 'PowerLimitOn:selectnumbers,500,500,4000,0,lin',\
PowerLimitOff => 'PowerLimitOff:selectnumbers,500,500,4000,0,lin',\
RunTimeMin => 'RunTimeMin:selectnumbers,300,300,14400,0,lin',\
RunTimePerDay => 'RunTimePerDay:selectnumbers,300,300,28200,0,lin',\
TimeStart => 'TimeStart:time',\
TimeEnd => 'TimeEnd:time'}
attr rg_LWP_Status group PV Status
attr rg_LWP_Status nameStyle style="color:grey"
attr rg_LWP_Status room Strom->Photovoltaik
attr rg_LWP_Status sortby 01
attr rg_LWP_Status style style="font-size:18px"


7. Aktivierung der Geräte mit Shelly 2.5
    Die Leistungsmessung der Shellys läst sich in diesem Zusammenhang auch sehr gut für das Feintuning verwenden.
    Dies ist auch ein Beispiel für sprintf mit HTML.

defmod shelly01 Shelly 192.168.178.54
attr shelly01 alias LWP_Signale
attr shelly01 group PV Eigenverbrauch-Steuerung
attr shelly01 icon taster_ch_1
attr shelly01 mode relay
attr shelly01 model shelly1pm
attr shelly01 room Shelly,Heizung->System,Strom->Photovoltaik
attr shelly01 sortby 02
attr shelly01 stateFormat {sprintf("\
<TABLE>\
\
<TR>\
  <TD VALIGN=\"TOP\" ALIGN=\"LEFT\" WIDTH=\"50\">\
    WebLink: %s\
  </TD>\
\
  <TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"100\">\
    Gesamt 0: %08.2f KWh<br>\
  </TD>\
\
  <TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"70\">\
    Relais 0: %s %06.1f Watt<br>\
  </TD>\
</TR>\
\
</TABLE>\
" ,\
ReadingsVal($name,"WebLink","none") ,\
ReadingsVal($name,"energy_0",0)/1000,\
(ReadingsVal($name,"relay","") eq "off") ? "<span style='color:#FF0000'>off</span>":"<span style='color:#00FF00'>on</span>",\
ReadingsVal($name,"power",0),\
)}
attr shelly01 userReadings WebLink { my $ip=ReadingsVal($NAME,"network","");; $ip =~ s/connected to //gs;; $ip =~ s/<[^>]*>//gs;; return("<html><a href='http://".$ip."/'>WEB</a></html>") }
attr shelly01 webCmd |


7.1 Mitlerweile habe ich die Shell2.5 gegen Shelly1 ausgetauscht. Der Grund war, dass die LWP nur einen Kanal benoetigt und fuer die Waschmaschine konnte der Shelly1 die hohe Leistung besser schalten.

defmod shelly01 Shelly 192.168.178.54
attr shelly01 alias LWP_Signale
attr shelly01 group PV Eigenverbrauch-Steuerung
attr shelly01 icon taster_ch_1
attr shelly01 mode relay
attr shelly01 model shelly1pm
attr shelly01 room Shelly,Heizung->System,Strom->Photovoltaik
attr shelly01 sortby 02
attr shelly01 stateFormat {sprintf("\
<TABLE>\
\
<TR>\
  <TD VALIGN=\"TOP\" ALIGN=\"LEFT\" WIDTH=\"50\">\
    WebLink: %s\
  </TD>\
\
  <TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"100\">\
    Gesamt 0: %08.2f KWh<br>\
  </TD>\
\
  <TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"70\">\
    Relais 0: %s %06.1f Watt<br>\
  </TD>\
</TR>\
\
</TABLE>\
" ,\
ReadingsVal($name,"WebLink","none") ,\
ReadingsVal($name,"energy_0",0)/1000,\
(ReadingsVal($name,"relay","") eq "off") ? "<span style='color:#FF0000'>off</span>":"<span style='color:#00FF00'>on</span>",\
ReadingsVal($name,"power",0),\
)}
attr shelly01 userReadings WebLink { my $ip=ReadingsVal($NAME,"network","");; $ip =~ s/connected to //gs;; $ip =~ s/<[^>]*>//gs;; return("<html><a href='http://".$ip."/'>WEB</a></html>") }
attr shelly01 webCmd |


Und hier noch die weiteren Geraete.

8. Der Wirlpool

defmod Pool_PV DOIF ################################################################################################################\
## 1 Eigenverbrauch abschalten: wenn Mindestlaufzeit erreicht wurde und Maximallaufzeit pro Tag erreicht ist\
##\
([Pool_Counter:pulseTimePerDay] >= [Pool:RunTimePerDay] and\
  [Pool_Counter:pulseTimeIncrement] >= [Pool:RunTimeMin] and\
  [Pool:state] eq "on" and [Pool:Pool_Button] eq "off" )\
\
    ({Log 3, "Pool_PV cmd_1 : Pool off"}\
     {fhem("".ReadingsVal("Pool","SetCmdOff",0))}\
     {fhem("set Pool off")})\
################################################################################################################\
## 2 Eigenverbrauch abschalten: wenn Mindestlaufzeit erreicht wurde und die PV-Produktion unter dem Mindestbedarf ist.\
##   Bei Pool Nutzung und Pflegeprogramm wird nicht abgeschaltet.\
##\
DOELSEIF\
([PV_Anlage_1:Total_PV_Power_reserve] < [Pool:PowerLimitOff] and\
  [Pool_Counter:pulseTimeIncrement] >= [Pool:RunTimeMin] and\
  [Pool:state] eq "on" and \
  [$SELF:cmd_nr] ne "5" and [$SELF:cmd_nr] ne "7" and [$SELF:cmd_nr] ne "10" )\
\
    ({Log 3, "Pool_PV cmd_2 : Pool off"}\
     {fhem("".ReadingsVal("Pool","SetCmdOff",0))}\
     {fhem("set Pool off")} )\
################################################################################################################\
## 3 Stop, wenn es nur ein kurzer Peak ist. Dieser Do Zweig setzt den wait timer vom Einschaltkommando cmd_4 wieder außer kraft,\
##   wenn während der Wartezeit die PV-Anlage zuwenig liefert.\
##\
DOELSEIF\
([PV_Anlage_1:Total_PV_Power_reserve] < [Pool:PowerLimitOff] and\
  [$SELF:wait_timer] ne "no timer" and\
  [$SELF:wait_timer] ne "" and\
  [Pool:state] eq "off" )\
\
    ({Log 3, "Pool_PV cmd_3 : Stop wait timer Pool"})\
################################################################################################################\
## 4 Eigenverbrauch einschalten: wenn PV-Produktion über dem Mindestbedarf ist und PV-Strom ins Netz eingespeist wird\
##    und die Laufzeit pro Tag noch nicht erreicht ist;; Bei über 7000 Watt Einspeisung sofort aktivieren\
##\
DOELSEIF\
(([PV_Anlage_1:Total_PV_Power_reserve] >= [Pool:PowerLimitOn] and\
   [[Pool:TimeStart]-[Pool:TimeEnd]] and\
   [Pool:state] eq "off" and\
   [Pool_Counter:pulseTimePerDay] < [Pool:RunTimePerDay]\
  ) or\
  [PV_Anlage_1:Total_active_power_(powermeter)] <= -7000\
)\
\
    ({Log 3, "Pool_PV cmd_4 : Pool on"}\
     {fhem("set Pool_Counter pulseTimeIncrement 0")}\
     {fhem("".ReadingsVal("Pool","SetCmdOn",0))}\
     {fhem("set Pool on")} )\
################################################################################################################\
## 5 Steckdose für die Benutzung des Pools einschalten.\
##\
DOELSEIF\
([Pool:Pool_Button] eq "on" )\
\
    ({Log 3, "Pool_PV cmd_5 : Pool on for usage"}\
     {fhem("".ReadingsVal("Pool","SetCmdOn",0))}\
     {fhem("set Pool on")} )\
################################################################################################################\
## 6 Steckdose des Pools abschalten.\
##\
DOELSEIF\
([Pool:Pool_Button] eq "off" and\
  [$SELF:cmd_nr] eq "5" or [$SELF:cmd_nr] eq "7")\
\
    ({Log 3, "Pool_PV cmd_6 : Pool off after usage"}\
     {fhem("".ReadingsVal("Pool","SetCmdOff",0))}\
     {fhem("set Pool off")} )\
################################################################################################################\
## 7 Stop wait Timer für das Abschalten, wenn die Pumpe beim Starten noch anläuft\
##\
DOELSEIF\
([shelly02:power_0] > 10 and\
  ([$SELF:cmd_nr] eq "5" or [$SELF:cmd_nr] eq "7" or [$SELF:cmd_nr] eq "9") and\
  [$SELF:wait_timer] ne "no timer" and\
  [$SELF:wait_timer] ne "" and\
  [Pool:state] eq "on" )\
\
    ({Log 3, "Pool_PV cmd_7 : Stop wait timer Pool"})\
################################################################################################################\
## 8 Pool Ende\
##\
DOELSEIF\
([shelly02:power_0] < 10 and\
  ([$SELF:cmd_nr] eq "5" or [$SELF:cmd_nr] eq "7" or [$SELF:cmd_nr] eq "9") )\
\
    ({Log 3, "Pool_PV cmd_8 : Pool run finished"}\
     {fhem("".ReadingsVal("Pool","SetCmdOff",0))}\
     {fhem("set Pool off")}\
     {fhem("setreading Pool Pool_Button off")} )\
################################################################################################################\
## 9 Pflege Zwangseinschaltung: Es muss mindestens einmal pro Tag eingeschaltet werden, auch wenn kein PV Strom vorhanden war.\
##\
DOELSEIF\
([[Pool:TimeEnd]] and\
  ([Pool_Counter:pulseTimePerDay] < [Pool:RunTimePerDay] or\
   [Pool_Counter:countsPerDay] eq 0)\
)\
\
    ({Log 3, "Pool_PV cmd_9 : Pool on for maintanance"}\
     {fhem("set Pool_Counter pulseTimeIncrement 0")}\
     {fhem("".ReadingsVal("Pool","SetCmdOn",0))}\
     {fhem("set Pool on")} )\
################################################################################################################\
## 10 Pflege Zwangseinschaltung bei günstigem Strom nachts im Winter\
##\
DOELSEIF\
([Astro:ObsSeason] eq "Winter" and\
  [Strom_Kosten:aWATTar_Trigger] eq "on" and\
  [22:00-05:00]\
)\
\
    ({Log 3, "Pool_PV cmd_10 : Pool on for maintanance by aWATTar"}\
     {fhem("set Pool_Counter pulseTimeIncrement 0")}\
     {fhem("".ReadingsVal("Pool","SetCmdOn",0))}\
     {fhem("set Pool on")} )\
################################################################################################################\
## 11 Abschaltung bei teurem Strom\
##\
DOELSEIF\
([Astro:ObsSeason] eq "Winter" and\
  [Strom_Kosten:aWATTar_Trigger] eq "off" and\
  [$SELF:cmd_nr] eq "10"\
)\
\
    ({Log 3, "Pool_PV cmd_11 : Pool off after maintanance by aWATTar"}\
     {fhem("".ReadingsVal("Pool","SetCmdOff",0))}\
     {fhem("set Pool off")} )
attr Pool_PV DbLogExclude .*
attr Pool_PV DbLogInclude cmd.*,state,cmd.*,Device,Pool_Pumpe_Status,wait_timer
attr Pool_PV alias Pool_PV
attr Pool_PV cmdState Maximalzeit pro Tag überschritten|Eigenverbrauch aus|Stop wait timer|Eigenverbrauch freigegeben|Pool ein für Benutzung|Pool aus nach Benutzung|Stop wait timer fuer aus|Pool aus|Pflegemodus ohne PV|Strombörse ein|Strombörse aus
attr Pool_PV disable 0
attr Pool_PV do always
attr Pool_PV event-on-change-reading .*
attr Pool_PV group PV Eigenverbrauch-Steuerung
attr Pool_PV icon scene_swimming
attr Pool_PV room Strom->Photovoltaik
attr Pool_PV sortby 11
attr Pool_PV stateFormat state : Pool_Pumpe_Status
attr Pool_PV userReadings Pool_Pumpe_Status { ReadingsVal("shelly02","power_0",0)>10 ? "Pool_Pumpe_laeuft" : "Pool_Pumpe_aus"}
attr Pool_PV verbose 0
attr Pool_PV wait 0:10:0:[Pool:PowerLevelMinTime]:0:0:0:300:0:300


9. Die Waschmaschine, es ist eine sehr alte mit Walzenschalter, sodass man vorhen alles einstellen kann und wenn dann die Steckdose einschaltet geht es einfach los ;-)

defmod Waschmaschine_PV DOIF ################################################################################################################\
## 1 Eigenverbrauch sperren: wenn Mindestlaufzeit erreicht wurde und Maximallaufzeit pro Tag erreicht ist\
##   jedoch nicht wenn manueller Betrieb aktiv ist.\
##\
([Waschmaschine_Counter:pulseTimePerDay] >= [Waschmaschine:RunTimePerDay] and\
  [Waschmaschine_Counter:pulseTimeIncrement] >= [Waschmaschine:RunTimeMin] and\
  [Waschmaschine:state] eq "on" and [Waschmaschine:Waschmaschine_Button] eq "off" )\
\
    ({Log 3, "Waschmaschine cmd_1 : Eigenverbrauch sperren"}\
     {fhem("".ReadingsVal("Waschmaschine","SetCmdOff",0))}\
     {fhem("setreading Waschmaschine_PV Waschmaschine_Status Steckdose ist ausgeschaltet")}\
     {fhem("set Waschmaschine off")}\
    )\
################################################################################################################\
## 2 Eigenverbrauch sperren: wenn Mindestlaufzeit erreicht wurde und die PV-Produktion unter dem Mindestbedarf ist\
##   ausser bei manuellem Einschalten und wenn das Waschprogramm bereits läuft\
##\
## ([PV_Anlage_1:Total_PV_Power_reserve] < [Waschmaschine:PowerLimitOff] and\
##  [Waschmaschine_Counter:pulseTimeIncrement] >= [Waschmaschine:RunTimeMin] and\
##\
DOELSEIF\
([PV_Anlage_1:Total_PV_Power_reserve] < [Waschmaschine:PowerLimitOn] and\
  [Waschmaschine:state] eq "on" and\
  [$SELF:cmd_nr] ne "5" and [$SELF:cmd_nr] ne "7" )\
\
    ({Log 3, "Waschmaschine cmd_2 : Eigenverbrauch sperren"}\
     {fhem("".ReadingsVal("Waschmaschine","SetCmdOff",0))}\
     {fhem("setreading Waschmaschine_PV Waschmaschine_Status Steckdose ist ausgeschaltet")}\
     {fhem("set Waschmaschine off")}\
    )\
################################################################################################################\
## 3 Stop, wenn es nur ein kurzer Peak ist. Dieser Do Zweig setzt den wait timer vom Einschaltkommando cmd_4\
##    wieder außer kraft, wenn während der Wartezeit die PV-Anlage zuwenig liefert.\
##\
DOELSEIF\
([PV_Anlage_1:Total_PV_Power_reserve] < [Waschmaschine:PowerLimitOff] and\
  [Waschmaschine_PV:wait_timer] ne "no timer" and\
  [Waschmaschine_PV:wait_timer] ne "" and\
  [Waschmaschine:state] eq "off" )\
\
    ({Log 3, "Waschmaschine cmd_3 : Waschmaschine stop wait timer"})\
################################################################################################################\
## 4 Eigenverbrauch freigeben: wenn PV-Produktion über dem Mindestbedarf ist und PV-Strom ins Netz eingespeist\
##   wird und die Laufzeit pro Tag noch nicht erreicht ist\
##\
DOELSEIF\
([PV_Anlage_1:Total_PV_Power_reserve] > [Waschmaschine:PowerLimitOn] and\
  [Waschmaschine:state] eq "off" and\
  [[Waschmaschine:TimeStart]-[Waschmaschine:TimeEnd]] and\
  [Waschmaschine_Counter:pulseTimePerDay] < [Waschmaschine:RunTimePerDay] )\
\
    ({Log 3, "Waschmaschine cmd_4 : Waschmaschine freigabe"}\
     {fhem("".ReadingsVal("Waschmaschine","SetCmdOn",0))}\
     {fhem("setreading Waschmaschine_PV Waschmaschine_Status Steckdose ist eingeschaltet")}\
     {fhem("set Waschmaschine on")}\
    )\
################################################################################################################\
## 5 Steckdose manuell für die Benutzung der Waschmaschine einschalten.\
##\
DOELSEIF\
([Waschmaschine:Waschmaschine_Button] eq "on" )\
\
    ({Log 3, "Waschmaschine cmd_5 : Waschmaschine manuell ein"}\
     {fhem("".ReadingsVal("Waschmaschine","SetCmdOn",0))}\
     {fhem("setreading Waschmaschine_PV Waschmaschine_Status Steckdose ist eingeschaltet")}\
     {fhem("set Waschmaschine on")}\
    )\
################################################################################################################\
## 6 Steckdose der Waschmaschine manuell abschalten.\
##\
DOELSEIF\
([Waschmaschine:Waschmaschine_Button] eq "off" and\
  ([$SELF:cmd_nr] eq "5" or [$SELF:cmd_nr] eq "7") )\
\
    ({Log 3, "Waschmaschine cmd_6 : Waschmaschine manuell aus"}\
     {fhem("".ReadingsVal("Waschmaschine","SetCmdOff",0))}\
     {fhem("setreading Waschmaschine_PV Waschmaschine_Status Steckdose ist ausgeschaltet")}\
     {fhem("set Waschmaschine off")}\
    )\
################################################################################################################\
## 7 Statuswechsel wenn das Waschprogramm gestartet ist\
##\
DOELSEIF\
([shelly03:power] > 0 and\
  [shelly03:power_Waschmaschine_avg] < 70 and\
  [$SELF:cmd_nr] ne "7")\
\
    ({Log 3, "Waschmaschine cmd_7 : Waschmaschine Programm gestarted"}\
     {fhem("setreading Waschmaschine_PV Waschmaschine_Status Waschprogramm gestartet")}\
    )\
################################################################################################################\
## 8 Abschalten der Steckdose beim Waschprogramm Ende\
##\
DOELSEIF\
([shelly03:power] == 0 and\
  [shelly03:power_Waschmaschine_avg] > 0 and\
  [$SELF:cmd_nr] eq "7" )\
\
    ({Log 3, "Waschmaschine cmd_8 : Waschmaschine aus"}\
     {fhem("".ReadingsVal("Waschmaschine","SetCmdOff",0))}\
     {fhem("set Waschmaschine off")}\
     {fhem("setreading Waschmaschine Waschmaschine_Button off")}\
     {fhem("setreading Waschmaschine_PV Waschmaschine_Status Waschprogramm beendet")}\
    )\
################################################################################################################\
## 9 Abschalten der Steckdose wenn die Waschmaschine nicht gebraucht wurde\
##\
DOELSEIF\
([PV_Anlage_1:Total_PV_Power_reserve] < [Waschmaschine:PowerLimitOn] and\
  [[Waschmaschine:TimeEnd]-[Waschmaschine:TimeStart]] and\
  [Waschmaschine:state] eq "on" and\
  [$SELF:cmd_nr] ne "5" and [$SELF:cmd_nr] ne "7" )\
\
    ({Log 3, "Waschmaschine cmd_9 : Eigenverbrauch sperren"}\
     {fhem("".ReadingsVal("Waschmaschine","SetCmdOff",0))}\
     {fhem("set Waschmaschine off")}\
     {fhem("setreading Waschmaschine Waschmaschine_Button off")}\
     {fhem("setreading Waschmaschine_PV Waschmaschine_Status Steckdose ist ausgeschaltet")}\
    )
attr Waschmaschine_PV DbLogExclude .*
attr Waschmaschine_PV DbLogInclude state,STATE,cmd.*,Device,Waschmaschine_Status,wait_timer
attr Waschmaschine_PV alias Waschmaschine_PV
attr Waschmaschine_PV cmdState Maximalzeit pro Tag überschritten|Eigenverbrauch gesperrt|Stop wait timer|Eigenverbrauch freigegeben|Waschmaschine manuell ein|Waschmaschine manuell aus|Waschmaschine laeuft|Waschmaschine aus|Eigenverbrauch gesperrt
attr Waschmaschine_PV do always
attr Waschmaschine_PV group PV Eigenverbrauch-Steuerung
attr Waschmaschine_PV icon scene_washing_machine
attr Waschmaschine_PV room Strom->Photovoltaik
attr Waschmaschine_PV sortby 21
attr Waschmaschine_PV stateFormat state : Waschmaschine_Status
attr Waschmaschine_PV verbose 0
attr Waschmaschine_PV wait 0:0:0:[Waschmaschine:PowerLevelMinTime]:0:30:0:60:30


Noch mehr Details kann ich gerne auf Rueckfrage geben, den es aendert sich ja immer etwas

Viele Grüße
     Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Fritz Muster

Hallo ch.eick,

habe mal ein paar Anmerkungen/Tipps zu Deinem Vorhaben der Eigenverbrauch Steuerung:

1. Sofern Du einen Trinkwasserspeicher hast, den Sollwert um 5-10K erhöhen wenn die PV genug Strom produziert
2. Trinkwassererwärmung nicht direkt über Heizstab machen, Wirkungsgrad ist da 1:1, besser Trinkwasser über sie WP machen, Wirkungsgrad ist da 1:2,irgendwas
3. Raumtemperatur Sollwert der Wärmepumpe um 2-3 K erhöhen wenn die PV genung Strom liefert, damit speicherst Du Wärmeennergie in Wände, Böden, Möbel
4. leichte Nachtabsenkung von Raumtemp Sollwert der Heizung, dann wird bei Tagesanbruch (Sonnenlicht) der Verlust mit Hilfe von PV Strom via Wärmepumpe "aufgeholt"


Grüße Fritz
RasPi 3B+, Stretch, Fhem 5.9, DBlog SQLite
HMLAN, mapleCUN MAX/WMBus, mapleSduino 868/433/868
HM Sensoren/Aktoren ,Technoline TX 29 DTH-IT, TFA 30.3155WD, MAX!
Hour Counter, Astro, EletricityCounter, Statistics, Charting Frontend, TabletUI, Modbus

ch.eick

Zitat von: Fritz Muster am 06 August 2019, 12:36:41
1. Sofern Du einen Trinkwasserspeicher hast, den Sollwert um 5-10K erhöhen wenn die PV genug Strom produziert
2. Trinkwassererwärmung nicht direkt über Heizstab machen, Wirkungsgrad ist da 1:1, besser Trinkwasser über sie WP machen, Wirkungsgrad ist da 1:2,irgendwas
3. Raumtemperatur Sollwert der Wärmepumpe um 2-3 K erhöhen wenn die PV genung Strom liefert, damit speicherst Du Wärmeennergie in Wände, Böden, Möbel
4. leichte Nachtabsenkung von Raumtemp Sollwert der Heizung, dann wird bei Tagesanbruch (Sonnenlicht) der Verlust mit Hilfe von PV Strom via Wärmepumpe "aufgeholt"

Hallo Fritz,

vielen Dank für Deine Rückmeldung, genau das soll laut Novelan Beschreibung die Heizungsanlage eigenständig machen. In der Zwischenzeit habe ich jedoch bereits erste Tests gemacht und die Novelan LAD9 macht noch nicht was sie soll. Ich bin mit dem Hersteller in Verbindung, jedoch ist noch nicht mehr wie, "Der Volumenstrom ist nicht gegeben" zurück gekommen. Nun habe ich Testergebnisse und Diagramme ein gesendet, auf die noch keine Rückmeldung kam.

Der Plan-B wäre dann die Werte mit dem Luxtronik Modul selber entsprechend umzusetzen, was ich mir jedoch ersparen wollte, wenn die Anlage es doch selber können soll.

   opModeHotWater von Auto auf Party
   hotWaterTemperatureTarget von 50 auf 65 (Maximalwert der LWP)
Eventuell mal kurz die Zirkulation anwerfen, damit es zu einer besseren Durchmischung kommt.

opModeHeating wird im Luxtronik Modul leider nicht zum setzen angeboten

Hier fehlen mir Tipps für Werte, damit "zu 3)" optimal umgesetzt werden kann.
   heatingCurveEndPoint 29.0
   heatingCurveOffset    21.0
Die Nachtabsenkung müsste glaube ich dann direkt eingestellt werden.


zu 2) Mit einem kleinen Heizstab (500-1000 Watt) würde sich trotzdem Leistung im Puffer speichern lassen. Die LWP benötigt ja direkt 3-4,5 KW für den Kompressor.
        Das ist zwar 1:1 jedoch immer noch geeignet auch kleine Einspeisungen für 10ct/KWh zu puffern. Das ist alles so eine Ansichtssache auch in Hinblick auf
        Kompressorverschleiß.
        Momentan habe ich leider nur zwei Heizstäbe mit je 9 KW, die vollkommen überdimensioniert sind eingebaut. Jedoch bin ich gelernter Elektriker und
        könnte die eventuell mit allen 6 Heizwiederständen in Reihe klemmen. Da komme ich dann auf ca 500W, wobei 250W im Heizbereich und 250W im
        Brauchwasserbereich positioniert sind. Da muss ich aber besser erst mal die Schaltung kontrollieren.
zu 3) Kann ich auch erreichen, dass im Puffer etwas mehr für die Nacht gespeichert wird??? Da fehlt mir noch der passende Wert zum verändern. Obwohl, wenn ich die
        Heizkurve verändere wird ja auch im Speicher die Temperatur geändert. Wer kann Da noch genaueres zu beantworten?
zu 4) Unser Haus verträgt auch eine große Nachtabsenkung :-) Der Energiepass sagt A+ .

Neuerdings haben wir zusätzlich auch noch einen Kaminofen, abends extrem gut durch heizt :-) Dann schaltet mein einziges Thermostat aber die FBH ab. Nur das Appartment wird dann noch von der Heizung versorgt und die KWL verteilt die Wärme sehr gut in der gesamten Wohnung.

Gerade habe ich mir die Warmwasserkurven mal angesehen. Sollte es gelingen den Speicher bis maximum aufzuheizen, dann kann ich mir im Sommer fast einen
LWP Zyklus einsparen und das bei Einsatz von PV-Strom wäre ja schon fast ein doppelter Erfolg ;-)

Ich werde in einiger Zeit die Eigenverbrauch Steuerung noch aktualisieren, da ich bereits einige Schritte weiter bin.

Die Anzahl der Geräte hat sich erhöht und die DOIFs habe ich auch noch auf einzelne Phasen erweitert.

Viele Grüße
    Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Fritz Muster

Zu Detailfragen zur LAD9 kann ich leider nicht weiterhelfen, da müssen andere ran ;-) Wenn Deine WP aber 9 KW hat und Deine Hütte A+ ist dann befürchte ich nichts Gutes!

Zitat von: ch.eick am 06 August 2019, 13:46:01
zu 2) Mit einem kleinen Heizstab (500-1000 Watt) würde sich trotzdem Leistung im Puffer speichern lassen. Die LWP benötigt ja direkt 3-4,5 KW für den Kompressor.
        Das ist zwar 1:1 jedoch immer noch geeignet auch kleine Einspeisungen für 10ct/KWh zu puffern. Das ist alles so eine Ansichtssache auch in Hinblick auf
        Kompressorverschleiß.
        Momentan habe ich leider nur zwei Heizstäbe mit je 9 KW, die vollkommen überdimensioniert sind eingebaut. Jedoch bin ich gelernter Elektriker und
        könnte die eventuell mit allen 6 Heizwiederständen in Reihe klemmen. Da komme ich dann auf ca 500W, wobei 250W im Heizbereich und 250W im
        Brauchwasserbereich positioniert sind. Da muss ich aber besser erst mal die Schaltung kontrollieren.

Bitte entschuldige, aber ich bin bin zu 100% anderer Meinung. Mein 275 Liter TW Speicher benötigt ca. 10KWh Wärmemenge um die Wassertemp. um ca. 10K anzuheben. 10KWh thermisch bedeuten dann bei einem WP-Wirkungsgrad von 2,5 ca. 4 KWh elektrisch. Mit Deinem Ansatz (250W Heizstab) bist Du dann aber seeehr lange im Gange um die sagen wir mal 10 K hinzukriegen. Was Du auch nicht mit einkalkulierst ist Deine 70% Regelung. Der entscheidende Benefit bei PV Anlagen mit 70% Regelung ensteht dann, wenn die Anlage über 70% erzeugt (je mehr je besser). Und das wird bei Deinem Konzept mit 250W Heizstab nicht viel bringen.

Ich denke hydraulisch ist bei Dir auch einiges noch im Argen bzw, schiefgelaufenn. Die Kombi aus Kamin und WP/FBH habe ich bis dato auch noch nie als Erfolgsmodell gesehen. Und ich habe es auch noch nie erlebt, das eine KWL die thermischen sagen wir mal 5 KW eines Ofens effizient im Haus verteilt hat.

Aber zu dem Thema würde ich Dir empfehlen mal im HTD Forum rein zu schauen. "Da werden Sie geholfen."

Zitat von: ch.eick am 06 August 2019, 13:46:01
Gerade habe ich mir die Warmwasserkurven mal angesehen. Sollte es gelingen den Speicher bis maximum aufzuheizen, dann kann ich mir im Sommer fast einen
LWP Zyklus einsparen und das bei Einsatz von PV-Strom wäre ja schon fast ein doppelter Erfolg ;-)

Wenn Du einen guten und vor allem richtig ausgelegten TW Speicher hast, dann reicht eine Speicherladung pro Tag vollkommen aus. Und diese Speicherladung findet dann im Zeitraum 12-14:00 Uhr statt. Aufgeladen auf ca. 50 °C hast Du auch am folgenden Morgen noch gute 40 °C im oberen Bereich was zum Duschen vollkommen reicht.

Viele Grüße
Fritz
RasPi 3B+, Stretch, Fhem 5.9, DBlog SQLite
HMLAN, mapleCUN MAX/WMBus, mapleSduino 868/433/868
HM Sensoren/Aktoren ,Technoline TX 29 DTH-IT, TFA 30.3155WD, MAX!
Hour Counter, Astro, EletricityCounter, Statistics, Charting Frontend, TabletUI, Modbus

ch.eick

Zitat
Zu Detailfragen zur LAD9 kann ich leider nicht weiterhelfen, da müssen andere ran ;-) Wenn Deine WP aber 9 KW hat und Deine Hütte A+ ist dann befürchte ich nichts Gutes!

Für die Novelan LAD9 stehe ich im Kontakt mit dem Hersteller und habe mich im Haustechnikdialog Forum aktiviert.
Was soll nicht gut sein? Ich habe noch ein Keller Appartment vermietet. Bei bisher tiefsten temperaturen hatte ich nur 5-6 Heizzyklen in 24h.
Ich verstehe die Befürchtung nicht ganz?
Die 9KW sind 2x 9KW Heizstäbe, die ich total überdimensioniert ansehe. Das passiert wenn man bei der Sanierung noch zu wenig Ahnung hat und die Planer angst haben. Bei der Heizstäben habe ich die sicherungen abgeschaltet. Das ist nur für minus 25°C Außentemparatur oder bei wochenlangem LWP Ausfall.

Zitat
Bitte entschuldige, aber ich bin bin zu 100% anderer Meinung. Mein 275 Liter TW Speicher benötigt ca. 10KWh Wärmemenge um die Wassertemp. um ca. 10K anzuheben. 10KWh thermisch bedeuten dann bei einem WP-Wirkungsgrad von 2,5 ca. 4 KWh elektrisch. Mit Deinem Ansatz (250W Heizstab) bist Du dann aber seeehr lange im Gange um die sagen wir mal 10 K hinzukriegen. Was Du auch nicht mit einkalkulierst ist Deine 70% Regelung. Der entscheidende Benefit bei PV Anlagen mit 70% Regelung ensteht dann, wenn die Anlage über 70% erzeugt (je mehr je besser). Und das wird bei Deinem Konzept mit 250W Heizstab nicht viel bringen.

Da bin ich ganz bei Dir. 250 W war nur ein Beispiel für die geringste Einheit, dass das dann ewig dauert ist schon verstanden. Ich dosiere in meinem Plan natürlich die Leistung entsprechend den Möglichkeiten der PV-Anlage. Natürlich mit dynamischer 70% Regelung, um alles raus zu holen. Deshalb habe ich auch diesen Thread eröffnet, um Mitstreiter zu finden.

Zitat
Ich denke hydraulisch ist bei Dir auch einiges noch im Argen bzw, schiefgelaufenn. Die Kombi aus Kamin und WP/FBH habe ich bis dato auch noch nie als Erfolgsmodell gesehen. Und ich habe es auch noch nie erlebt, das eine KWL die thermischen sagen wir mal 5 KW eines Ofens effizient im Haus verteilt hat.

Aber zu dem Thema würde ich Dir empfehlen mal im HTD Forum rein zu schauen. "Da werden Sie geholfen."

Hydrausch ist es echt top. Bei geringem LWP Einsatz sind alle Räume, auch das Bad optimal geheizt. Es werden keinerlei Raumthermostate benötigt, die ich deshalb schon gegen Schakter mit Kontrolleuchte ersetzt habe, um in der Übergangszeit meinen Mieter schon heizen lassen zu können und bei mir einfach abzuschalten.

Der Kamin ist bei uns nachträglich als Luxusobjekt dazu gekommen. Die Abschaltung der FBH ist reiner Selbstschutz :-) wegen der warmen Füße.
Bei uns sind ca. 70% der Wohnfläche ein offener Bereich und natürlich schafft eine KWL nicht alles gleichmäßig zu verteilen. Ein Temperatusanstieg ist jedoch nach kurzer Zeit auch in den anderen Räumen zu messen (analoges Thermometer vom Opa).

Zitat
Wenn Du einen guten und vor allem richtig ausgelegten TW Speicher hast, dann reicht eine Speicherladung pro Tag vollkommen aus. Und diese Speicherladung findet dann im Zeitraum 12-14:00 Uhr statt. Aufgeladen auf ca. 50 °C hast Du auch am folgenden Morgen noch gute 40 °C im oberen Bereich was zum Duschen vollkommen reicht.

Exakt so ist es bei uns. Ich lade jedoch um 14:00 Uhr für 30-40 Minuten, dann habe ich die beste Außentemperatur.
Meine Testwerte mit der Maximalaufheizung durch die LWP über PV-Strom haben ergeben, dass ich damit dann ca. 48h auskomme, also einen intensieveren Lauf der LWP mit günstigem Strom und dann erst wieder zwei Tage später. Ich finde das echt toll.



RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Fritz Muster

RasPi 3B+, Stretch, Fhem 5.9, DBlog SQLite
HMLAN, mapleCUN MAX/WMBus, mapleSduino 868/433/868
HM Sensoren/Aktoren ,Technoline TX 29 DTH-IT, TFA 30.3155WD, MAX!
Hour Counter, Astro, EletricityCounter, Statistics, Charting Frontend, TabletUI, Modbus

ch.eick

Hallo zusammen,

ich habe dann mal die RAW definitionen im ersten post auf den aktuellen Stand gebracht und noch etwas für die Ansteuerung mit Shelly 2.5 Aktoren ergänzt.
Weitere Schritte folgen dann nach der Lieferung und dem Aufbau der Photovoltaik in ca 5 Wochen.
Anbei noch einige Bilder wie das ganze nun im FHEM aussieht.

Sollte jemand an den weiteren device definitionen interesse haben, so kann er dies gerne hier kund tun.

Viele Grüße
    Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hallo zusammen,

hier kommt dann mal ein kleines Update zum Kostal EM410 in Verbindung mit dem Kostal Plenticore 10

Entgegen meinen ersten Informationen muss der EM410 über den rs485 Bus mit dem Plenticore 10 verbunden werden, da nur so die Regelung der Leistung im Haus und zum Speicher möglich ist. Insider munkeln, dass jedoch bereits an der Firmware des Plenticore entwichelt wird, um die Modbus TCP kommunikation stattdessen zu nutzen. Somit musste ich noch den rs485 Bus vom Keller zum Dachboden zwischen den beiden Geräten nachrüsten. Nun läuft alles soweit.

Nun zum Modbus TCP, über das Haus Lan.

Der Plenticore 10 spricht direkt über das Lan das Modbus TCP Protokoll, nachdem man es aktiviert hat. Somit kann man mit dem Modbus Modul im Fhem alle bereitgestellten Werte, inklusieve der des EM410 abrufen.
Die bisherige Definition sieht dann im Fhem für alle Modbus Register so aus:

defmod PV_Anlage_1 ModbusAttr 71 60 192.168.178.18:1502 TCP
attr PV_Anlage_1 alias PV_Einspeisung
attr PV_Anlage_1 comment Kostal Plenticore 10 Plus mit BYD Speicher
attr PV_Anlage_1 dev-h-defFormat %.2f
attr PV_Anlage_1 dev-h-defLen 2
attr PV_Anlage_1 dev-h-defPoll 1
attr PV_Anlage_1 dev-h-defRevRegs 1
attr PV_Anlage_1 dev-h-defUnpack f>
attr PV_Anlage_1 dev-type-STR-format %s
attr PV_Anlage_1 dev-type-STR-len 8
attr PV_Anlage_1 dev-type-STR-revRegs 0
attr PV_Anlage_1 dev-type-STR-unpack a*
attr PV_Anlage_1 group PV Eigenverbrauch
attr PV_Anlage_1 icon sani_solar
attr PV_Anlage_1 obj-h100-reading Total_DC_Power
attr PV_Anlage_1 obj-h104-format %s
attr PV_Anlage_1 obj-h104-reading State_of_energy_manager
attr PV_Anlage_1 obj-h104-revRegs 0
attr PV_Anlage_1 obj-h104-unpack N
attr PV_Anlage_1 obj-h106-reading Home_own_consumption_from_battery
attr PV_Anlage_1 obj-h108-reading Home_own_consumption_from_grid
attr PV_Anlage_1 obj-h110-reading Total_home_consumption_Battery
attr PV_Anlage_1 obj-h112-reading Total_home_consumption_Grid
attr PV_Anlage_1 obj-h114-reading Total_home_consumption_PV
attr PV_Anlage_1 obj-h116-reading Home_own_consumption_from_PV
attr PV_Anlage_1 obj-h118-reading Total_home_consumption
attr PV_Anlage_1 obj-h120-reading Isolation_resistance
attr PV_Anlage_1 obj-h122-reading Power_limit_from_EVU
attr PV_Anlage_1 obj-h124-reading Total_home_consumption_rate
attr PV_Anlage_1 obj-h14-reading Inverter_serial_number
attr PV_Anlage_1 obj-h14-type STR
attr PV_Anlage_1 obj-h144-reading Worktime
attr PV_Anlage_1 obj-h150-reading Actual_cos_phi
attr PV_Anlage_1 obj-h152-reading Grid_frequency
attr PV_Anlage_1 obj-h154-reading Current_Phase_1
attr PV_Anlage_1 obj-h156-reading Active_power_Phase_1
attr PV_Anlage_1 obj-h158-reading Voltage_Phase_1
attr PV_Anlage_1 obj-h160-reading Current_Phase_2
attr PV_Anlage_1 obj-h162-reading Active_power_Phase_2
attr PV_Anlage_1 obj-h164-reading Voltage_Phase_2
attr PV_Anlage_1 obj-h166-reading Current_Phase_3
attr PV_Anlage_1 obj-h168-reading Active_power_Phase_3
attr PV_Anlage_1 obj-h170-reading Voltage_Phase_3
attr PV_Anlage_1 obj-h172-reading Total_AC_active_power
attr PV_Anlage_1 obj-h174-reading Total_AC_reactive_power
attr PV_Anlage_1 obj-h178-reading Total_AC_apparent_power
attr PV_Anlage_1 obj-h190-reading Battery_charge_current
attr PV_Anlage_1 obj-h194-format %.0f
attr PV_Anlage_1 obj-h194-reading Number_of_battery_cycles
attr PV_Anlage_1 obj-h200-reading Actual_battery_charge_-minus_or_discharge_-plus_current
attr PV_Anlage_1 obj-h202-reading PSSB_fuse_state
attr PV_Anlage_1 obj-h208-format %.0f
attr PV_Anlage_1 obj-h208-reading Battery_ready_flag
attr PV_Anlage_1 obj-h210-reading Act_state_of_charge
attr PV_Anlage_1 obj-h212-reading Battery_state
attr PV_Anlage_1 obj-h214-reading Battery_temperature
attr PV_Anlage_1 obj-h216-reading Battery_voltage
attr PV_Anlage_1 obj-h218-reading Cos_phi_(powermeter)
attr PV_Anlage_1 obj-h220-reading Frequency_(powermeter)
attr PV_Anlage_1 obj-h222-reading Current_phase_1_(powermeter)
attr PV_Anlage_1 obj-h224-reading Active_power_phase_1_(powermeter)
attr PV_Anlage_1 obj-h226-reading Reactive_power_phase_1_(powermeter)
attr PV_Anlage_1 obj-h228-reading Apparent_power_phase_1_(powermeter)
attr PV_Anlage_1 obj-h230-reading Voltage_phase_1_(powermeter)
attr PV_Anlage_1 obj-h232-reading Current_phase_2_(powermeter)
attr PV_Anlage_1 obj-h234-reading Active_power_phase_2_(powermeter)
attr PV_Anlage_1 obj-h236-reading Reactive_power_phase_2_(powermeter)
attr PV_Anlage_1 obj-h238-reading Apparent_power_phase_2_(powermeter)
attr PV_Anlage_1 obj-h240-reading Voltage_phase_2_(powermeter)
attr PV_Anlage_1 obj-h242-reading Current_phase_3_(powermeter)
attr PV_Anlage_1 obj-h244-reading Active_power_phase_3_(powermeter)
attr PV_Anlage_1 obj-h246-reading Reactive_power_phase_3_(powermeter)
attr PV_Anlage_1 obj-h248-reading Apparent_power_phase_3_(powermeter)
attr PV_Anlage_1 obj-h250-reading Voltage_phase_3_(powermeter)
attr PV_Anlage_1 obj-h252-reading Total_active_power_(powermeter)
attr PV_Anlage_1 obj-h254-reading Total_reactive_power_(powermeter)
attr PV_Anlage_1 obj-h256-reading Total_apparent_power_(powermeter)
attr PV_Anlage_1 obj-h258-reading Current_DC1
attr PV_Anlage_1 obj-h260-reading Power_DC1
attr PV_Anlage_1 obj-h266-reading Voltage_DC1
attr PV_Anlage_1 obj-h268-reading Current_DC2
attr PV_Anlage_1 obj-h270-reading Power_DC2
attr PV_Anlage_1 obj-h276-reading Voltage_DC2
attr PV_Anlage_1 obj-h278-reading Current_DC3
attr PV_Anlage_1 obj-h280-reading Power_DC3
attr PV_Anlage_1 obj-h286-reading Voltage_DC3
attr PV_Anlage_1 obj-h320-reading Total_yield
attr PV_Anlage_1 obj-h322-reading Daily_yield
attr PV_Anlage_1 obj-h324-reading Yearly_yield
attr PV_Anlage_1 obj-h326-reading Monthly_yield
attr PV_Anlage_1 obj-h38-reading Software-Version_Maincontroller_(MC)
attr PV_Anlage_1 obj-h38-type STR
attr PV_Anlage_1 obj-h384-len 16
attr PV_Anlage_1 obj-h384-reading Inverter_network_name
attr PV_Anlage_1 obj-h384-type STR
attr PV_Anlage_1 obj-h420-reading IP-address
attr PV_Anlage_1 obj-h420-type STR
attr PV_Anlage_1 obj-h428-reading IP-subnetmask
attr PV_Anlage_1 obj-h428-type STR
attr PV_Anlage_1 obj-h436-reading IP-gateway
attr PV_Anlage_1 obj-h436-type STR
attr PV_Anlage_1 obj-h446-reading IP-DNS1
attr PV_Anlage_1 obj-h446-type STR
attr PV_Anlage_1 obj-h454-reading IP-DNS2
attr PV_Anlage_1 obj-h454-type STR
attr PV_Anlage_1 obj-h46-reading Software-Version_IO-Controller_(IOC)
attr PV_Anlage_1 obj-h46-type STR
attr PV_Anlage_1 obj-h514-len 1
attr PV_Anlage_1 obj-h514-reading Battery_actual_SOC
attr PV_Anlage_1 obj-h517-reading Battery_Manufacturer
attr PV_Anlage_1 obj-h517-type STR
attr PV_Anlage_1 obj-h525-format %c
attr PV_Anlage_1 obj-h525-reading Battery_Model_ID
attr PV_Anlage_1 obj-h525-unpack N
attr PV_Anlage_1 obj-h527-format %c
attr PV_Anlage_1 obj-h527-reading Battery_Serial_Number
attr PV_Anlage_1 obj-h529-len 4
attr PV_Anlage_1 obj-h529-reading Work_Capacity
attr PV_Anlage_1 obj-h529-unpack N
attr PV_Anlage_1 obj-h531-format %.0f
attr PV_Anlage_1 obj-h531-reading Inverter_Max_Power
attr PV_Anlage_1 obj-h531-unpack N
attr PV_Anlage_1 obj-h535-revRegs 0
attr PV_Anlage_1 obj-h535-unpack n
attr PV_Anlage_1 obj-h551-revRegs 0
attr PV_Anlage_1 obj-h559-revRegs 0
attr PV_Anlage_1 obj-h56-format %.0f
attr PV_Anlage_1 obj-h56-reading Inverter_state
attr PV_Anlage_1 obj-h56-unpack N
attr PV_Anlage_1 obj-h575-len 1
attr PV_Anlage_1 obj-h575-reading Inverter_Generation_Power_(actual)
attr PV_Anlage_1 obj-h577-len 2
attr PV_Anlage_1 obj-h577-reading Generation_Energy
attr PV_Anlage_1 obj-h577-unpack N
attr PV_Anlage_1 obj-h578-reading Total_energy
attr PV_Anlage_1 obj-h582-reading Actual_battery_charge-discharge_power
attr PV_Anlage_1 obj-h586-format %s
attr PV_Anlage_1 obj-h586-reading Battery_Firmware
attr PV_Anlage_1 obj-h586-unpack N
attr PV_Anlage_1 obj-h588-format %s
attr PV_Anlage_1 obj-h588-len 1
attr PV_Anlage_1 obj-h588-reading Battery_Type
attr PV_Anlage_1 obj-h588-unpack N
attr PV_Anlage_1 obj-h6-reading Inverter_article_number
attr PV_Anlage_1 obj-h6-type STR
attr PV_Anlage_1 obj-h768-len 32
attr PV_Anlage_1 obj-h768-reading Productname
attr PV_Anlage_1 obj-h768-type STR
attr PV_Anlage_1 obj-h800-len 32
attr PV_Anlage_1 obj-h800-reading Power_class
attr PV_Anlage_1 obj-h800-type STR
attr PV_Anlage_1 room Strom->Photovoltaik
attr PV_Anlage_1 sortby 01
attr PV_Anlage_1 stateFormat {sprintf("\
<TABLE>\
\
<TR>\
  <TH VALIGN=\"TOP\" ALIGN=\"MIDDLE\" WIDTH=\"60\">Batterie %s</TH>\
  <TH VALIGN=\"TOP\" ALIGN=\"MIDDLE\" WIDTH=\"60\">aktuell</TH>\
  <TH VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"60\">Hausverbrauch</TH>\
</TR>\
\
<TR>\
  <TD VALIGN=\"TOP\" ALIGN=\"MIDDLE\" WIDTH=\"60\">\
    Leistung:  %04d W<br>\
    Temp.: %02.1f °C<br>\
    Ladung total: %2d %%<br>\
    Ladung Res.: %04d Wh\
  </TD>\
\
  <TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"60\">\
    DC total: %05d W<br>\
    <br>\
    <br>\
    PV reserve: %05d W\
  </TD>\
\
  <TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"60\">\
    von PV: %05d W <br>\
    von Batterie: %05d W<br>\
    vom Netz: %05d W<br>\
    ins Haus: %05d W\
  </TD>\
</TR>\
\
</TABLE>\
" , \
(ReadingsVal($name,"Actual_battery_charge_-minus_or_discharge_-plus_Power",0) lt 0) ? "<span style='color:#00FF00'>Laden</span>":"<span style='color:#FF0000'>Entladen</span>" ,\
\
ReadingsVal($name,"Actual_battery_charge_-minus_or_discharge_-plus_Power",0),\
ReadingsVal($name,"Battery_temperature",0) ,\
ReadingsVal($name,"Act_state_of_charge",0) ,\
ReadingsVal($name,"Actual_battery_charge_usable_Power",0) ,\
\
ReadingsVal($name,"Power_DC1","0")+ReadingsVal($name,"Power_DC2","0"),\
ReadingsVal($name,"Power_DC1","0")+ReadingsVal($name,"Power_DC2","0")-ReadingsVal($name,"Total_AC_active_power","0"),\
\
ReadingsVal($name,"Home_own_consumption_from_PV",0) ,\
ReadingsVal($name,"Home_own_consumption_from_battery",0) ,\
ReadingsVal($name,"Home_own_consumption_from_grid",0),\
ReadingsVal($name,"Home_own_consumption_from_PV",0) +ReadingsVal($name,"Home_own_consumption_from_battery",0)+ReadingsVal($name,"Home_own_consumption_from_grid",0)\
)}
attr PV_Anlage_1 userReadings Total_PV_Power_reserve:Total_DC_Power.* {ReadingsVal($NAME,"Power_DC1","0")+ReadingsVal($NAME,"Power_DC2","0")-ReadingsVal($NAME,"Total_AC_active_power","0")},\
Actual_battery_charge_-minus_or_discharge_-plus_Power:Actual_battery_charge_-minus_or_discharge_-plus_current.* {round((ReadingsVal($NAME,"Actual_battery_charge_-minus_or_discharge_-plus_current","0")*ReadingsVal($NAME,"Battery_voltage","0")),0)},\
Actual_battery_charge_usable_Power:Act_state_of_charge.* {round((8760*(ReadingsVal($NAME,"Act_state_of_charge","0")-10)/100),0)}
attr PV_Anlage_1 verbose 0

Im Anhang sieht man das Ergebnis in der Zeile "PV_Einspeisung"

Weiterhin sind noch zwei userReadings hinzugefügt, die in der Eigenverbrauchssteuerung bzw für die verwendbare Leistung im Speicher sind:

Dieser Wert gibt eine Auskunft über die aktuelle Restleistung, die ohne Speichernutzung gerade noch verbraucht werden könnte. Schaltet man einen
Verbraucher ein, der in diesen Wert passt, dann wird ein etwaiges Laden des Speichers unterbrochen.

Total_PV_Power_reserve:Total_DC_Power.* {ReadingsVal($NAME,"Power_DC1","0")+ReadingsVal($NAME,"Power_DC2","0")-ReadingsVal($NAME,"Total_AC_active_power","0")}


Hier wir der Lade/Entladestrom in Leistung umgerechnet P=U*I  :-)

Actual_battery_charge_-minus_or_discharge_-plus_Power:Actual_battery_charge_-minus_or_discharge_-plus_current.* {round((ReadingsVal($NAME,"Actual_battery_charge_-minus_or_discharge_-plus_current","0")*ReadingsVal($NAME,"Battery_voltage","0")),0)}


Mit dieser Berechnung bekommt man ein Gefühl wieviel Leistung noch im Speicher vorgehalten wird. Bei meiner Konfiguration wird der Speicher bis
maximal 10% entladen, um einer Tiefentladung entgegen zu wirken. Werte größer 0 Wh könnten in die Entscheidung zum Einschalten eines Verbrauchers
einbezogen werden. Der Wert ist als Schätzung zu betrachten, da er von der Nennleistung, bei meinem Speicher 8,76 KW und dem 10% Wert aus geht.
Es werden Wh angegeben, die natürlich auch noch von weitern Faktoren abhängen. Hier wäre zB die Umgebungstemperatur des Speichers, Volllast oder
nur kleine Last zu erwähnen. Ein Erfahrungswert liegt noch nicht vor.

Actual_battery_charge_usable_Power:Act_state_of_charge.* {round((8760*(ReadingsVal($NAME,"Act_state_of_charge","0")-10)/100),0)}




Achtung, ich editiere noch weiter!!!!
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Moin,

ich habe den ersten Post mal wieder aktualisiert. Da ist zwar nur das Beispiel fuer die Waermepumpe beschrieben, aber auf Wunsch kann ich auch noch folgende Geraete liefern.

1. Waermepumpe
2. Wirlpool (Softtube) ueber Steckdose An/Aus
3. Waschmaschine ueber Steckdose An/Aus

Steuerungsparameter sind jeweils:

Pool_Button
PowerLevelMinTime
PowerLimitOff
PowerLimitOn
RunTimeMin
RunTimePerDay
SetCmdOff
SetCmdOn
TimeEnd
TimeStart

Ein Logik Beispiel anhand des Pools waere:

1) Eigenverbrauch abschalten: wenn Mindestlaufzeit erreicht wurde und Maximallaufzeit pro Tag erreicht ist

2) Eigenverbrauch abschalten: wenn Mindestlaufzeit erreicht wurde und die PV-Produktion unter dem Mindestbedarf ist. Bei Pool Nutzung und Pflegeprogramm wird nicht abgeschaltet.

3) Stop, wenn es nur ein kurzer PV-Peak ist. Dies setzt den wait timer vom Einschaltkommando wieder außer kraft, wenn während der Wartezeit (PowerLevelMinTime) die PV-Anlage zuwenig liefert.

4) Eigenverbrauch einschalten: wenn PV-Produktion über dem Mindestbedarf ist und PV-Strom ins Netz eingespeist wird und die Laufzeit pro Tag noch nicht erreicht ist.

5) Steckdose für die Benutzung des Pools einschalten.

6) Steckdose des Pools abschalten.

7) Pool Ende wenn die Temperaturregelung stimmt und die Pumpe ausgegangen ist. Der Pool bleibt nach der Benutzung an, bis die Temperatur stimmt.

8) Pflege Zwangseinschaltung: Es muss mindestens einmal pro Tag eingeschaltet werden, auch wenn kein PV Strom vorhanden war.


Bei der Waschmaschine wird anhand des Stromverbrauchs der Waschprogramm Start und das Ende erkannt. Hier kann man die Meldung aufs Handy ankoppeln :-)

Viele Gruesse
    Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

EDIT 2020.01.10 : Herzlich willkommen nun sind wir schon drei :-)

Na das ist ja mager :-) Nur ein anderer, der den Thread gut findet...
Dann warte ich doch noch etwas weiter.

Viele Grüße
     Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Soooooo,

hier kommt schon mal der erste Test für den EM410/KSEM mit der modbus tcp Abfrage. Es sind zwar noch nicht alle Werte korrekt, aber das kommt dann als Änderung.
Mit der Firmware 1.1.2 auf dem KSEM werden nun auch die modbus tcp Register gefüllt. Ich hatte da Kontakt mit Kostal, da bisher alle Werte auf Null standen.
Nach dem Aufspielen der Firmware musste auch noch ein Reset des Plenticore durchgeführt werden, da dieser anscheinend die Verbindung über rs485 verloren hatte.

Remote:
Der Reset ist jedoch nicht einfach über die Web Oberfläche möglich. Beim Zurücksetzen auf die Werkseinstellungen wird anschließend ein Reset gemacht, jedoch verliert man dabei die konfigurierten Einstellungen.
Ich habe den Reset dann durch das Neuladen der selben Firmware erzwungen, das ist zwar nicht die Feine Art, jedoch bleiben hierbei alle Einstellungen erhalten.
EDIT 2020.04.02 : Ueber die Plenticore API kann man auch mit einem Python Skript einen Reset durchfuehren. Da bin ich jedoch noch am Testen.

Vorort:
Der Kostal Weg ist der Reset vorort, der im Handbuch beschrieben ist.

Hier nun die ersten KSEM modbus tcp definitionen:

defmod PV_EM410 ModbusAttr 1 60 192.168.178.17:502 TCP
attr PV_EM410 alias PV_Energy_Manager
attr PV_EM410 comment Kostal EM410 Energy Manager
attr PV_EM410 dev-h-defPoll 1
attr PV_EM410 dev-type-INT16-expr $val/100
attr PV_EM410 dev-type-INT16-format %.2f
attr PV_EM410 dev-type-INT16-len 1
attr PV_EM410 dev-type-INT16-unpack n
attr PV_EM410 dev-type-STR32-format %s
attr PV_EM410 dev-type-STR32-len 16
attr PV_EM410 dev-type-STR32-unpack a*
attr PV_EM410 dev-type-UINT16-format %s
attr PV_EM410 dev-type-UINT16-len 1
attr PV_EM410 dev-type-UINT32-format %s
attr PV_EM410 dev-type-UINT32-len 2
attr PV_EM410 dev-type-UINT64-format %s
attr PV_EM410 dev-type-UINT64-len 4
attr PV_EM410 group PV Eigenverbrauch
attr PV_EM410 icon measure_power
attr PV_EM410 obj-h40071-expr $val/10000
attr PV_EM410 obj-h40071-reading M_AC_Current
attr PV_EM410 obj-h40071-type INT16
attr PV_EM410 obj-h40072-reading M_AC_Current_A
attr PV_EM410 obj-h40072-type INT16
attr PV_EM410 obj-h40073-reading M_AC_Current_B
attr PV_EM410 obj-h40073-type INT16
attr PV_EM410 obj-h40074-reading M_AC_Current_C
attr PV_EM410 obj-h40074-type INT16
attr PV_EM410 obj-h40076-reading M_AC_Voltage_LN
attr PV_EM410 obj-h40076-type INT16
attr PV_EM410 obj-h40077-reading M_AC_Voltage_AN
attr PV_EM410 obj-h40077-type INT16
attr PV_EM410 obj-h40078-reading M_AC_Voltage_BN
attr PV_EM410 obj-h40078-type INT16
attr PV_EM410 obj-h40079-reading M_AC_Voltage_CN
attr PV_EM410 obj-h40079-type INT16
attr PV_EM410 obj-h40080-reading M_AC_Voltage_LL
attr PV_EM410 obj-h40080-type INT16
attr PV_EM410 obj-h40081-reading M_AC_Voltage_AB
attr PV_EM410 obj-h40081-type INT16
attr PV_EM410 obj-h40082-reading M_AC_Voltage_BC
attr PV_EM410 obj-h40082-type INT16
attr PV_EM410 obj-h40083-reading M_AC_Voltage_CA
attr PV_EM410 obj-h40083-type INT16
attr PV_EM410 obj-h40085-reading M_AC_Freq
attr PV_EM410 obj-h40085-type INT16
attr PV_EM410 obj-h40086-type INT16
attr PV_EM410 obj-h40087-expr $val*10
attr PV_EM410 obj-h40087-reading M_AC_Power
attr PV_EM410 obj-h40087-type INT16
attr PV_EM410 obj-h40088-expr $val*10
attr PV_EM410 obj-h40088-reading M_AC_Power_A
attr PV_EM410 obj-h40088-type INT16
attr PV_EM410 obj-h40089-expr $val*10
attr PV_EM410 obj-h40089-reading M_AC_Power_B
attr PV_EM410 obj-h40089-type INT16
attr PV_EM410 obj-h40090-expr $val*10
attr PV_EM410 obj-h40090-reading M_AC_Power_C
attr PV_EM410 obj-h40090-type INT16
attr PV_EM410 obj-h40092-reading M_AC_VA
attr PV_EM410 obj-h40092-type INT16
attr PV_EM410 obj-h40093-reading M_AC_VA_A
attr PV_EM410 obj-h40093-type INT16
attr PV_EM410 obj-h40094-reading M_AC_VA_B
attr PV_EM410 obj-h40094-type INT16
attr PV_EM410 obj-h40095-reading M_AC_VA_C
attr PV_EM410 obj-h40095-type INT16
attr PV_EM410 obj-h40097-reading M_AC_VAR
attr PV_EM410 obj-h40097-type INT16
attr PV_EM410 obj-h40098-reading M_AC_VAR_A
attr PV_EM410 obj-h40098-type INT16
attr PV_EM410 obj-h40099-reading M_AC_VAR_B
attr PV_EM410 obj-h40099-type INT16
attr PV_EM410 obj-h40100-reading M_AC_VAR_C
attr PV_EM410 obj-h40100-type INT16
attr PV_EM410 obj-h40102-expr $val/1000
attr PV_EM410 obj-h40102-reading M_AC_PF
attr PV_EM410 obj-h40102-type INT16
attr PV_EM410 obj-h40103-expr $val/1000
attr PV_EM410 obj-h40103-reading M_AC_PF_A
attr PV_EM410 obj-h40103-type INT16
attr PV_EM410 obj-h40104-expr $val/1000
attr PV_EM410 obj-h40104-reading M_AC_PF_B
attr PV_EM410 obj-h40104-type INT16
attr PV_EM410 obj-h40105-expr $val/1000
attr PV_EM410 obj-h40105-reading M_AC_PF_C
attr PV_EM410 obj-h40105-type INT16
attr PV_EM410 obj-h8192-reading ManufacturerID
attr PV_EM410 obj-h8192-type UINT16
attr PV_EM410 obj-h8193-reading ProductID
attr PV_EM410 obj-h8193-type UINT16
attr PV_EM410 obj-h8194-reading ProductVersion
attr PV_EM410 obj-h8194-type UINT16
attr PV_EM410 obj-h8195-reading FirmwareVersion
attr PV_EM410 obj-h8195-type UINT16
attr PV_EM410 obj-h8196-reading VendorName
attr PV_EM410 obj-h8196-type STR32
attr PV_EM410 obj-h8212-reading Productname
attr PV_EM410 obj-h8212-type STR32
attr PV_EM410 obj-h8228-reading SerialNumber
attr PV_EM410 obj-h8228-type STR32
attr PV_EM410 obj-h8244-reading MeasuringInterval
attr PV_EM410 obj-h8244-type UINT16
attr PV_EM410 room Strom->Photovoltaik
attr PV_EM410 sortby 02
attr PV_EM410 verbose 0


Viele Grüße
     Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hallo zusammen,

aus Dokumentationsgruenden habe ich heute den ersten Thread mal wieder aktualisiert.

Viele Gruesse
   Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hallo zusammen,
ich habe im grossen weiten Netz mal wieder etwas zur Kommunikation mit dem Plenticore Plus gefunden. Hier schon mal vorab vielen Dank an die Urheber.
Im folgenden handelt es sich nicht um meine Codierung, sondern nur um die Anwendung aus folgender Quelle:
https://stackoverflow.com/questions/59053539/api-call-portation-from-java-to-python-kostal-plenticore-inverter

Das bisherige Beispiel zum Auslesen ueber die API des Plenticore

fhem@raspberrypi:~/python/kostal$ cat plenticore_info.py
#####
##
## https://stackoverflow.com/questions/59053539/api-call-portation-from-java-to-python-kostal-plenticore-inverter?answertab=active#tab-top
##
## pip3 install pycryptodome
##

import sys
import random
import string
import base64
import json
import requests
import hashlib
import os
import hmac
from Crypto.Cipher import AES
import binascii

plenticore = sys.argv[1]

try:
    with open('/opt/fhem/python/pwd_plenticore.json', 'r') as f:
        credentials=json.load(f)
except Exception as e:
    print('Something went wrong: {}'.format(e))



USER_TYPE = credentials["username"]
PASSWD = credentials["password"]
BASE_URL = "http://" + plenticore + "/api/v1"
AUTH_START = "/auth/start"
AUTH_FINISH = "/auth/finish"
AUTH_CREATE_SESSION = "/auth/create_session"
ME = "/auth/me"

def randomString(stringLength):
    letters = string.ascii_letters
    return ''.join(random.choice(letters) for i in range(stringLength))

u = randomString(12)
u = base64.b64encode(u.encode('utf-8')).decode('utf-8')

step1 = {
  "username": USER_TYPE,
  "nonce": u
}
step1 = json.dumps(step1)

url = BASE_URL + AUTH_START
headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
response = requests.post(url, data=step1, headers=headers)
response = json.loads(response.text)
i = response['nonce']
e = response['transactionId']
o = response['rounds']
a = response['salt']
bitSalt = base64.b64decode(a)

def getPBKDF2Hash(password, bytedSalt, rounds):
    return hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), bytedSalt, rounds)

r = getPBKDF2Hash(PASSWD,bitSalt,o)
s = hmac.new(r, "Client Key".encode('utf-8'), hashlib.sha256).digest()
c = hmac.new(r, "Server Key".encode('utf-8'), hashlib.sha256).digest()
_ = hashlib.sha256(s).digest()
d = "n=user,r="+u+",r="+i+",s="+a+",i="+str(o)+",c=biws,r="+i
g = hmac.new(_, d.encode('utf-8'), hashlib.sha256).digest()
p = hmac.new(c, d.encode('utf-8'), hashlib.sha256).digest()
f = bytes(a ^ b for (a, b) in zip(s, g))
proof = base64.b64encode(f).decode('utf-8')

step2 = {
  "transactionId": e,
  "proof": proof
}
step2 = json.dumps(step2)

url = BASE_URL + AUTH_FINISH
headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
response = requests.post(url, data=step2, headers=headers)
response = json.loads(response.text)
token = response['token']
signature = response['signature']

y = hmac.new(_, "Session Key".encode('utf-8'), hashlib.sha256)
y.update(d.encode('utf-8'))
y.update(s)
P = y.digest()
protocol_key = P
t = os.urandom(16)

e2 = AES.new(protocol_key,AES.MODE_GCM,t)
e2, authtag = e2.encrypt_and_digest(token.encode('utf-8'))

step3 = {
  "transactionId": e,
  "iv": base64.b64encode(t).decode('utf-8'),
  "tag": base64.b64encode(authtag).decode("utf-8"),
  "payload": base64.b64encode(e2).decode('utf-8')
}
step3 = json.dumps(step3)

headers = { 'Content-type': 'application/json', 'Accept': 'application/json' }
url = BASE_URL + AUTH_CREATE_SESSION
response = requests.post(url, data=step3, headers=headers)
response = json.loads(response.text)
sessionId = response['sessionId']

#create a new header with the new Session-ID for all further requests
headers = { 'Content-type': 'application/json', 'Accept': 'application/json', 'authorization': "Session " + sessionId }
url = BASE_URL + ME
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
authOK = response['authenticated']
if not authOK:
    print("authorization NOT OK")
    sys.exit()

url = BASE_URL + "/info/version"
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
swversion = response['sw_version']
apiversion = response['api_version']
hostname = response['hostname']
name = response['name']
print("Connected to the inverter " + name + "/" + hostname + " with SW-Version " + swversion + " and API-Version " + apiversion)

# Auth OK, now send your desired requests


url = BASE_URL + "/auth/me"
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
print(json.dumps(response, indent=4, sort_keys=True))


url = BASE_URL + "/settings"
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
print(json.dumps(response, indent=4, sort_keys=True))


url = BASE_URL + "/modules"
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
print(json.dumps(response, indent=4, sort_keys=True))


url = BASE_URL + "/processdata"
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
print(json.dumps(response, indent=4, sort_keys=True))


url = BASE_URL + "/firmwareupdate/status"
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
print(json.dumps(response, indent=4, sort_keys=True))


url = BASE_URL + "/update/status"
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
print(json.dumps(response, indent=4, sort_keys=True))


url = BASE_URL + "/events/latest"
response = requests.get(url = url, headers = headers)
response = json.loads(response.text)
print(json.dumps(response, indent=4, sort_keys=True))

Das Passwort File sieht dann so aus

{
    "username": "user",
    "password": "Das Passwort steht auf dem Typenschild"
}

Ein Aufruf mit nur einer Abfrage koennte dann so aussehen

fhem@raspberrypi:~/python/kostal$ python3 ./plenticore_info.py <Ip-Adresse>
Connected to the inverter PUCK RESTful API/scb with SW-Version 01.13.04122 and API-Version 0.2.0
{
    "active": true,
    "anonymous": false,
    "authenticated": true,
    "locked": false,
    "permissions": [],
    "role": "USER"
}


Auch eine Anbindung an FHEM mit den gelesenen Daten waere als Muster bereits fertig. Ich habe es hier nur noch nicht gelistet.

Fuer das Setzen von Werten steht noch ein Service Request bei Kostal aus, das sollte dann noch etwas dauern :-)
EDIT: Nun ist auch ein Setzen von z.B von [{"moduleid":"devices:local","settingids":["Battery:MinSoc"]}] moeglich.
Ich arbeite dann mal an der FHEM Anbindung...

Viele Gruesse
      Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

stolus

@ch.eick Vielen Dank für den Thread und Deine Infos..
Ich habe gerade meinen EM410 und den Kostal Plenticore mit neuer Software upgedatet.
Und werde mich jetzt an die Integration in FHEM machen.

Ich habe seid kurzer Zeit eine Brauchwasserwärmepumpe die ich abhängig vom Solarstrom schalten möchte.
FHEM im Proxmox LXC
Raspberrymatic mit HB-RF-USB-2 für Homematic
ESPEasy/Tasmota/Shelly
Bayernlüfter, Plenticore Solar mit KSME EM410, EVCC mit E-Auto
Vailliant Arotherm Plus Wp mit ebus

ch.eick

Na dann passt es ja genau.

Einiges geht jedoch nur über Python:
- Statistiken
- MinSoc setzen
- Plenticore Reset

Gruß Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick