E3DC per RSCP, erster Erfolg, noch einiges zu testen

Begonnen von Dirk070, 06 August 2022, 17:03:43

Vorheriges Thema - Nächstes Thema

pcbastler

Es entwickelt sich :) Mit dem MQTT2-Server lässt sich mittels
set MQTT2_FHEM_Server publish e3dc/reserve/energy 8000Die Notstromreserve absolut setzen. Schick wäre das natürlich als Slider mit Prozenten direkt per setlist.
Ich scheitere allerdings schon damit, den eingestellten Wert anzeigen zu lassen.
attr S10E setlist reserve:slider,'reserve_percent',10,60,1  e3dc/set/reserve/procent $EVTPART1Oder bin ich da komplett auf dem Holzweg?

docolli

Nachdem ich mit Modbus bei meinem E3DC S10E nun an Grenzen stoße, habe ich mir auf meinem Raspi auch rscp2mqtt gebaut, läuft auch und gibt mir die Werte auf der Konsole aus.
Leider schaffe ich die MQTT Anbindung nicht, obwohl ich auf meiner FHEM Installation bereits einige MQTT Geräte erfolgreich eingebunden habe.
Mit dem MQTT Explorer auf meinem Laptop bekomme ich die e3dc topics, wenn ich mich mit dem Raspi verbinde.

Ich nehme die MQTT2 Implementierung von FHEM.
defmod Mqtt MQTT2_SERVER 1883 global
attr Mqtt autocreate simple
attr Mqtt hideRetain 0

Starte ich rscp2mqtt, so erhöht sich ´nrclients`um 1.
Leider schaffe ich es nicht, ein device für mein E3DC anzulegen, welches mir die MQTT Werte anzeigt.
Was nicht geht ist dies
define e3dc_s10_rscp MQTT2_DEVICE Mqtt
Hat jemand einen guten Rat für mich?

pcbastler

Auf den ersten Blick sieht das ok aus. Gibt es eine Fehlermeldung im Log?

Dirk070

Den MQTTSERVER habe ich im DEFINE identisch, bei den Attributen aber nur autocreate no.

docolli

Mir ist aufgefallen, dass alle MQTT Geräte, die in meiner FHEM Installation funktionieren, eine feste ClientID im Gerät eingestellt haben. Das rscp2mqtt Gerät jedoch liefert über die Mosquitobibliothek stets eine neue, zufällige Client ID.

Ich habe nun im Quellcode in der Datei RscpMqttMain.cpp in Zeile 1621 die Verbindung mit einer festen ClientID versehen, dann geht es bei mir:

mosq = mosquitto_new("rscp2mqtt", true, NULL);
Mein define sieht dann so aus (ClientID als letzter Parameter):

define e3dc_s10_rscp MQTT2_DEVICE rscp2mqtt

docolli

Zitat von: pcbastler am 01 Dezember 2023, 16:44:44Es entwickelt sich :) Mit dem MQTT2-Server lässt sich mittels
set MQTT2_FHEM_Server publish e3dc/reserve/energy 8000Die Notstromreserve absolut setzen. Schick wäre das natürlich als Slider mit Prozenten direkt per setlist.
Ich scheitere allerdings schon damit, den eingestellten Wert anzeigen zu lassen.
attr S10E setlist reserve:slider,'reserve_percent',10,60,1  e3dc/set/reserve/procent $EVTPART1Oder bin ich da komplett auf dem Holzweg?

Meiner Meinung nach müsste es oben so lauten
set MQTT2_FHEM_Server publish e3dc/set/reserve/energy 8000Du kannst auch nicht den Wert als Prozentwert setzen, das geht nur als energy (also kWh).

h002

Zitat von: Dirk070 am 15 Dezember 2023, 14:51:17Den MQTTSERVER habe ich im DEFINE identisch, bei den Attributen aber nur autocreate no.

Ich habe mich die Tage auch damit beschäftigt und habe ein Lösung mit Hilfe von Beta-User im Einsatz. Vielleicht hilft die diese Topic weiter. Die Echtzeitdaten kommen in eine InfluxDB, wo ich anschließend mit Grafana schöne bunte Bilder erzeugen kann. Die Daten für die Historie (Jahr, Monat) schreibe ich mittel dbLog in eine MySQL DB.

Nachdem die beiden Devices MQTT2_e3dc und MQTT2_e3dc_history angelegt wurde, kann man mittels publish e3dc/set/force mit dem Wert "1" alle Readings empfangen, anpassen und danach autocreate wieder deaktivieren (außer bei dem History-Device).

Die beiden Devices wurde automatisch mit folgendem Bridge-Device erzeugt. 

Internals:
   FUUID      6213f737-f33f-8b20-71e1-c63d824644905145
   IODev      MQTTClient
   NAME       MQTTClient_Bridge
   NR         161
   STATE      ???
   TYPE       MQTT2_DEVICE
   READINGS:
     2024-01-03 12:10:37   IODev           MQTTClient
Attributes:
   IODev      MQTTClient
   autocreate 1
   bridgeRegexp owntracks/[^/]+/([^/:]+).* "owntracks_$1"
e3dc/([^/]+).* "e3dc"
e3dc/history/([^/]+).* "e3dc_history_$1"
   icon       mqtt_bridge_2
   model      MQTT2_CLIENT_general_bridge
   room       MQTT2_DEVICE

Mein MQTT2_DEVICE für laufende Daten

Internals:
   CID        e3dc
   DEF        e3dc
   FUUID      6591a31e-f33f-8b20-efbc-7090aa8fe2ef1cd5
   IODev      MQTTClient
   LASTInputDev MQTTClient
   MQTTClient_MSGCNT 438202
   MQTTClient_TIME 2024-01-04 17:33:18
   MSGCNT     438202
   NAME       MQTT2_e3dc
   NR         212
   TYPE       MQTT2_DEVICE
   eventCount 438202
   READINGS:
     2024-01-03 12:10:37   IODev           MQTTClient
     2024-01-04 17:19:42   autarky         29.5
     2024-01-04 17:19:42   autarky_month   22.3
     2024-01-04 17:19:42   autarky_week    22.3
     ...
     2024-01-03 13:16:46   zone            Europe/Berlin
Attributes:
   alias      E3DC/S10
   autocreate 0
   icon       measure_photovoltaic_inst@green
   readingList e3dc/solar/power:.* power_solar
e3dc/battery/power:.* power_battery
e3dc/home/power:.* power_home
e3dc/grid/power:.* power_grid
e3dc/battery/soc:.* soc_battery
e3dc/pm/power/L1:.* power_L1
e3dc/pm/power/L2:.* power_L2
e3dc/pm/power/L3:.* power_L3
e3dc/battery/dcb/2/max_charge_current:.* dcb_2_max_charge_current
e3dc/pm/voltage/L1:.* voltage_L1
e3dc/pm/voltage/L2:.* voltage_L2
e3dc/pm/voltage/L3:.* voltage_L3
e3dc/system/software:.* software
e3dc/system/production_date:.* production_date
e3dc/system/serial_number:.* serial_number
e3dc/time/zone:.* zone
e3dc/system/installed_peak_power:.* installed_peak_power
e3dc/system/derate_at_percent_value:.* derate_at_percent_value
e3dc/system/derate_at_power_value:.* derate_at_power_value
e3dc/battery/rsoc:.* rsoc
e3dc/battery/voltage:.* voltage_battery
e3dc/battery/current:.* current_battery
e3dc/battery/cycles:.* cycles_battery
e3dc/battery/status:.* status_battery
e3dc/battery/error:.* error_battery
e3dc/battery/name:.* name_battery
e3dc/battery/dcb/count:.* count_battery
e3dc/battery/training:.* training_battery
e3dc/battery/temperature/max:.* max_battery
e3dc/battery/temperature/min:.* min_battery
e3dc/pvi/frequency:.* frequency
e3dc/pvi/temperature/count:.* count
e3dc/pvi/on_grid:.* on_grid
e3dc/reserve/percent:.* percent_reserve
e3dc/reserve/energy:.* energy_reserve
e3dc/reserve/max:.* max_reserve
e3dc/reserve/last_soc:.* last_soc_reserve
e3dc/battery/energy/charge:.* charge_battery
e3dc/battery/energy/discharge:.* discharge_battery
e3dc/solar/energy:.* energy_solar
e3dc/grid/energy/in:.* in_grid
e3dc/grid/energy/out:.* out_grid
e3dc/home/energy:.* energy_home
e3dc/pm_0/energy:.* energy_pm0
e3dc/pm_1/energy:.* energy_pm1
e3dc/consumed:.* consumed
e3dc/autarky:.* autarky
e3dc/yesterday/battery/energy/charge:.* charge_yesterday
e3dc/yesterday/battery/energy/discharge:.* discharge_yesterday
e3dc/yesterday/solar/energy:.* energy_solar_yesterday
e3dc/yesterday/grid/energy/in:.* in_grid_yesterday
e3dc/yesterday/grid/energy/out:.* out_grid_yesterday
e3dc/yesterday/home/energy:.* energy_home_yesterday
e3dc/yesterday/pm_0/energy:.* energy_yesterday
e3dc/yesterday/pm_1/energy:.* energy_yesterday
e3dc/yesterday/battery/rsoc:.* rsoc_yesterday
e3dc/yesterday/consumed:.* consumed_yesterday
e3dc/yesterday/autarky:.* autarky_yesterday
e3dc/week/battery/energy/charge:.* charge_week
e3dc/week/battery/energy/discharge:.* discharge_week
e3dc/week/solar/energy:.* energy_solar_week
e3dc/week/grid/energy/in:.* in_grid_week
e3dc/week/grid/energy/out:.* out_grid_week
e3dc/week/home/energy:.* energy_home_week
e3dc/week/consumed:.* consumed_week
e3dc/week/autarky:.* autarky_week
e3dc/month/battery/energy/charge:.* charge_month
e3dc/month/battery/energy/discharge:.* discharge_month
e3dc/month/solar/energy:.* energy_solar_month
e3dc/month/grid/energy/in:.* in_grid_month
e3dc/month/grid/energy/out:.* out_grid_month
e3dc/month/home/energy:.* energy_home_month
e3dc/month/consumed:.* consumed_month
e3dc/month/autarky:.* autarky_month
e3dc/year/battery/energy/charge:.* charge_year
e3dc/year/battery/energy/discharge:.* discharge_year
e3dc/year/solar/energy:.* energy_solar_year
e3dc/year/grid/energy/in:.* in_grid_year
e3dc/year/grid/energy/out:.* out_grid_year
e3dc/year/home/energy:.* energy_home_year
e3dc/year/consumed:.* consumed_year
e3dc/year/autarky:.* autarky_year
e3dc/battery/dcb/1/max_charge_voltage:.* dcb_1_max_charge_voltage
e3dc/battery/dcb/1/max_discharge_current:.* dcb_1_max_discharge_current
e3dc/battery/dcb/1/full_charge_capacity:.* dcb_1_full_charge_capacity
e3dc/battery/dcb/1/remaining_capacity:.* dcb_1_remaining_capacity
e3dc/battery/dcb/1/soc:.* dcb_1_soc
e3dc/battery/dcb/1/soh:.* dcb_1_soh
e3dc/battery/dcb/1/cycles:.* dcb_1_cycles
e3dc/battery/dcb/1/current:.* dcb_1_current
e3dc/battery/dcb/1/voltage:.* dcb_1_voltage
e3dc/battery/dcb/1/current_avg_30s:.* dcb_1_current_avg_30s
e3dc/battery/dcb/1/nr_sensor:.* dcb_1_nr_sensor
e3dc/battery/dcb/1/design_capacity:.* dcb_1_design_capacity
e3dc/battery/dcb/1/design_voltage:.* dcb_1_design_voltage
e3dc/battery/dcb/1/charge_low_temperature:.* dcb_1_charge_low_temperature
e3dc/battery/dcb/1/charge_high_temperature:.* dcb_1_charge_high_temperature
e3dc/battery/dcb/1/manufacture_date:.* dcb_1_manufacture_date
e3dc/battery/dcb/1/serial_number:.* dcb_1_serial_number
e3dc/battery/dcb/1/protocol_version:.* dcb_1_protocol_version
e3dc/battery/dcb/1/firmware_version:.* dcb_1_firmware_version
e3dc/battery/dcb/1/table_version:.* dcb_1_table_version
e3dc/battery/dcb/1/pcb_version:.* dcb_1_pcb_version
e3dc/battery/dcb/1/nr_series_cell:.* dcb_1_nr_series_cell
e3dc/battery/dcb/1/nr_parallel_cell:.* dcb_1_nr_parallel_cell
e3dc/battery/dcb/1/manufacture_name:.* dcb_1_manufacture_name
e3dc/battery/dcb/1/device_name:.* dcb_1_device_name
e3dc/battery/dcb/1/serial_code:.* dcb_1_serial_code
e3dc/battery/dcb/2/max_charge_voltage:.* dcb_2_max_charge_voltage
e3dc/battery/dcb/2/max_discharge_current:.* dcb_2_max_discharge_current
e3dc/battery/dcb/2/full_charge_capacity:.* dcb_2_full_charge_capacity
e3dc/battery/dcb/2/remaining_capacity:.* dcb_2_remaining_capacity
e3dc/battery/dcb/2/soc:.* dcb_2_soc
e3dc/battery/dcb/2/soh:.* dcb_2_soh
e3dc/battery/dcb/2/cycles:.* dcb_2_cycles
e3dc/battery/dcb/2/current:.* dcb_2_current
e3dc/battery/dcb/2/voltage:.* dcb_2_voltage
e3dc/battery/dcb/2/current_avg_30s:.* dcb_2_current_avg_30s
e3dc/battery/dcb/2/voltage_avg_30s:.* dcb_2_voltage_avg_30s
e3dc/battery/dcb/2/nr_sensor:.* dcb_2_nr_sensor
e3dc/battery/dcb/2/design_capacity:.* dcb_2_design_capacity
e3dc/battery/dcb/2/design_voltage:.* dcb_2_design_voltage
e3dc/battery/dcb/2/charge_low_temperature:.* dcb_2_charge_low_temperature
e3dc/battery/dcb/2/charge_high_temperature:.* dcb_2_charge_high_temperature
e3dc/battery/dcb/2/manufacture_date:.* dcb_2_manufacture_date
e3dc/battery/dcb/2/serial_number:.* dcb_2_serial_number
e3dc/battery/dcb/2/protocol_version:.* dcb_2_protocol_version
e3dc/battery/dcb/2/firmware_version:.* dcb_2_firmware_version
e3dc/battery/dcb/2/table_version:.* dcb_2_table_version
e3dc/battery/dcb/2/pcb_version:.* dcb_2_pcb_version
e3dc/battery/dcb/2/nr_series_cell:.* dcb_2_nr_series_cell
e3dc/battery/dcb/2/nr_parallel_cell:.* dcb_2_nr_parallel_cell
e3dc/battery/dcb/2/manufacture_name:.* dcb_2_manufacture_name
e3dc/battery/dcb/2/device_name:.* dcb_2_device_name
e3dc/battery/dcb/2/serial_code:.* dcb_2_serial_code
e3dc/pvi/temperature/1:.* temperature_1
e3dc/pvi/temperature/2:.* temperature_2
e3dc/pvi/temperature/3:.* temperature_3
e3dc/pvi/temperature/4:.* temperature_4

Mein History-Device

Internals:
   CID        e3dc_history_2020
   DEF        e3dc_history_2020
   FUUID      6591accf-f33f-8b20-a290-0a7fb1e365cba3ee
   IODev      MQTTClient
   LASTInputDev MQTTClient
   MQTTClient_MSGCNT 64
   MQTTClient_TIME 2024-01-03 13:16:50
   MSGCNT     64
   NAME       MQTT2_e3dc_history
   NR         213
   TYPE       MQTT2_DEVICE
   eventCount 64
   
   READINGS:

     2024-01-03 12:10:37   IODev           MQTTClient
Attributes:
   autocreate 1
   readingList e3dc/history/[^:]+:.* { my @toptree = split m{/}x, $TOPIC;; shift @toptree;; shift @toptree;; my $rname = join q{_}, @toptree;; return {$rname => $EVENT}}
   room       MQTT2_DEVICE

Mein MQTT2_DEVICE für Historie

Internals:
   CID        e3dc_history_2020
   DEF        e3dc_history_2020
   FUUID      6591accf-f33f-8b20-a290-0a7fb1e365cba3ee
   IODev      MQTTClient
   LASTInputDev MQTTClient
   MQTTClient_MSGCNT 64
   MQTTClient_TIME 2024-01-03 13:16:50
   MSGCNT     64
   NAME       MQTT2_e3dc_history
   NR         213
   TYPE       MQTT2_DEVICE
   eventCount 64
   
   READINGS:

     2024-01-03 12:10:37   IODev           MQTTClient
Attributes:
   autocreate 1
   readingList e3dc/history/[^:]+:.* { my @toptree = split m{/}x, $TOPIC;; shift @toptree;; shift @toptree;; my $rname = join q{_}, @toptree;; return {$rname => $EVENT}}
   room       MQTT2_DEVICE

hkueller

#22
Ertrags und Überschuss abschätzung für E3DC (lässt sich sicher auch mit anderen PV Anlagen ähnlich nutzen).

Ich habe neben der E3DC S10 PV-Anlage noch eine Hargassner Pellets Heizung mit Bufferspeicher, sowie ein my-PV Heizstab (3kW) im Bufferspeicher. Ausserdem noch eine Wallbox für unseren PHEV.
die Hargassner Heizung kann ich mittels eines Smarhome Schalters (eigenbau basierend auf AskSin++ HM-LC-SW1-BA-PCB) blockieren. Das soll passieren, wenn zu erwarten ist, das der angeschlossene Batteriespeicher (12kWh) über Tags geladen wird, und trotzdem noch genügend Energie für den Heizstab zu erwarten ist. Auch den Wallbox Lademodus möchte ich in abhängigkeit vom erwarteten Überschuss schalten.
Als Unterstützung dazu hab ich in FHEM ein "Wetter" Gerät mit dem Modul "PROPLANTA" eingerichtet. Wie das geht ist im FHEM wiki, wie auch hier im Forum zu finden.
Weiterhin verwende ich ein Gerät "astro_data" vom type Astro (siehe ebenfalls wiki bzw. Forum)
Als basis werte brauch ich jetzt noch die Ertrags Erwartung.
Diese hab ich mittels dem attribute userReadings als zusätzliches Attribut für die E3DC S10 definiert:
attr E3DC userReadings ertrag_erwartung:eigenverbrauch.* {
  #Ich habe 2 Ertragsstränge, einen nach Osten ausgerichtet, einen nach Westen;
  #Diese sind bei mir im E3DC define entsprechend den beiden PV Strängen der Anlage definiert;
  my $pv_ostleistung=3550
  my $pv_westleistung=6390
  #Diverse Definitionen mit hilfe von astro_data um
  #am ende zu wissen, wann die Sonne aufgeht (beginn der Stromerzeugung)
  #wann die Sonne unter geht (ende der Stromerzeugung)
  #Die Sonne den Südlichsten Punkt errecht (danach kommt der Hauptertrag von Westen)
  my @DayEnd;
  my @AktHour = split ( /:/,strftime('%H:%M',localtime));
  my @DayStart = split( /:/,ReadingsVal("astro_data","CustomTwilightMorning",0));
  my @Noon = split( /:/,ReadingsVal("astro_data","SunTransit",0));
  my @SunData = split( / /,ReadingsVal("astro_data","SunPvData",0));
  my @OstTime = split( /:/,$SunData[0]);
  my @WestTime = split ( /:/,$SunData[2]);
  if ( $SunData[3] gt 25) {
    @DayEnd = split( /:/,ReadingsVal("astro_data","CustomTwilightEvening",0));
  } else {
    @DayEnd = split ( /:/,$SunData[1] );
  }
  #Wir brauchen die Daten im Minuten
  my $day_start=(($DayStart[0]* 60) + $DayStart[1]);
  my $day_len=(($DayEnd[0]* 60) + $DayEnd[1]) - $day_start;
  my $day_time = (($AktHour[0]* 60) + $AktHour[1]);
  my $pv_sum=0;
  my $Cloud=0;
  for ( my $i=$day_time;; $i < (($DayEnd[0]*60) + $DayEnd[1]);; $i++ ) {
    if ( $i > (($DayStart[0]* 60) + $DayStart[1]) ) {
      my $CloudTime=(int($i / 60 / 3) * 3);
      if ( $CloudTime < 10 ) {
        $Cloud = 100 - ReadingsVal("Wetter",sprintf("fc0_cloud0%d",$CloudTime),0);
      } else {
        $Cloud = 100 - ReadingsVal("Wetter",sprintf("fc0_cloud%d",$CloudTime),0);
      }
    my $SunMin=$day_len - ($day_len - ($i - $day_start));
      if ( $i < (($Noon[]* 60) + $Noon[1]) ) {
        $pv_sum = $pv_sum + ( ( sin( $SunMin*(3.14159/$day_len) ) * $pv_ostleistung) / 60 ) * ($Cloud / 100);
      } elsif ( $i < (($DayEnd[0]* 60) + $DayEnd[1]) ) {
        $pv_sum= $pv_sum + ( ( sin( $SunMin*(3.14159/$day_len) ) * $pv_westleistung ) / 60 ) * ($Cloud / 100);
      }
    }
  }
  sprintf("%5.2f",$pv_sum);
}

Die Berechnung hat nicht den Anspruch absolut genau zu sein, und gibt nur einen Näherungswert an.
Dabei ist nicht mit einbezogen, das die Zellen nur bei Auftreffen des Lichts im Rechten Winkel den vollen Ertrag bringen.
Auch ist (nicht ganz richtig) davon ausgegangen worden, das der Ertrag über den Tag analog zu einer Sinuskurve verhält. Die Ertragseinbußen durch Bewölkung sind auch eher annahmen.
In der Praxis komm ich aber mit dem hier berechneten Ergebniss für meine Zwecke ganz gut klar.
Vielleicht hilft das ja jemanden, der ähnliche anforderungen hat.
Verbesserungen sind natürlich immer willkommen.

Viele Grüße
Harald
fhem auf Fedora KVM instance mit >300 Homematic Devices

hkueller

#23
Leider liefert die Anlage keine kWh angaben zu den verbauten Batterien.
Aber es gibt die Amperstunden, sowie die Spannung der jeweiligen batterien.
Damit lässt sich die Leistung relativ einfach berechnen:
attr E3DC userReadings
batterie1_kwh { ReadingsVal("E3DC","batterie1_AH",0) * ReadingsVal("E3DC","batterie1_V",0) / 1000;; },
ReadingsVal("E3DC","batterie2_AH",0) * ReadingsVal("E3DC","batterie2_V",0) /1000;; },
ReadingsVal("E3DC","batterie3_AH",0) * ReadingsVal("E3DC","batterie3_V",0) /1000;; },
ReadingsVal("E3DC","batterie4_AH",0) * ReadingsVal("E3DC","batterie4_V",0) /1000;; }
Daraus kann jezt problemlos die gesammtkapzität der Batterien berechnet werden (das Ergebniss weicht bei mir von der Herstellerangabe ab!):
attr E3DC userReadings
batterie_max_kwh { ReadingsVal("E3DC","batterie1_kwh",0) + ReadingsVal("E3DC","batterie2_kwh",0) + ReadingsVal("E3DC","batterie3_kwh",0) + ReadingsVal("E3DC","batterie4_kwh",0);; }
fhem auf Fedora KVM instance mit >300 Homematic Devices

Init

Ich habe mal eine Frage in die Runde und muss dabei betonen, dass ich mich eher als Laie einstufe.
Warum verfolgt ihr den Umweg über mqtt und e3dc-rest statt direkt ein Modul zu bauen, welches python-e3dc nutzt?

pcbastler

python-e3dc ist auch nur eine Umsetzung der RSCP-Schnittstelle. Die E3DC-Geräte können nur ModBus (read-only) und RSCP. Modbus gibt es bereits, für RSCP braucht es bisher immer einen "Übersetzer". Da war MQTT die erste Wahl, das ist z.B. auch für Zigbee (zigbee2mqtt) nutzbar. Für ein natives als perl-RSCP-Modul hat sich noch niemand gefunden.