From 1384d8d5ed3bb3873f0e521f66c69ce30c3b4596 Mon Sep 17 00:00:00 2001 From: "ch.eick" <> Date: Thu, 25 Jan 2024 09:59:51 +0000 Subject: [PATCH] ch.eick: Next update git-svn-id: https://svn.fhem.de/fhem/trunk@28417 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- .../Wachmaschine_Shell_2.5/.gitkeep | 0 .../Kia_Node-Red_Flow.txt | 0 .../Kia_connect_bluelinky.txt | 39 + .../Kia_eNiro_Steuerung.txt | 782 +++++++++++ .../WB_0_DbLog_manuelle_Einträge.txt | 413 ++++++ .../WB_1_openWB.txt | 263 ++++ .../Wechselrichter/RAW_WR_0_KSEM.txt | 181 +++ .../Photovoltaik/Wechselrichter/RAW_WR_1.txt | 353 +++++ .../Wechselrichter/RAW_WR_1_API.txt | 854 +++++++++++ .../RAW_WR_1_Speicher_1_ExternControl.txt | 985 +++++++++++++ .../Photovoltaik/Wechselrichter/RAW_WR_2.txt | 109 ++ .../Wechselrichter/RAW_WR_2_API.txt | 328 +++++ .../Wechselrichter/RAW_WR_3_Fake_WR.txt | 49 + .../Wechselrichter/RAW_WR_ctl.txt | 495 +++++++ .../Photovoltaik/Wirlpool_Shelly_2.5/.gitkeep | 0 .../Wärmepumpe_Novelan_LAD9/.gitkeep | 0 .../Strombörse/EVU_Tibber/RAW_EVU_Tibber.txt | 264 ++++ .../EVU_Tibber/RAW_EVU_Tibber_connect.txt | 1250 +++++++++++++++++ .../RAW_LogDBRep_EVU_Tibber_connect_SQL.txt | 5 + .../EVU_aWATTar/RAW_EVU_aWATTar.txt | 191 +++ .../RAW_LogDBRep_EVU_aWATTar_connect_SQL.txt | 5 + 21 files changed, 6566 insertions(+) create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wachmaschine_Shell_2.5/.gitkeep create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_Node-Red_Flow.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_connect_bluelinky.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_eNiro_Steuerung.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/WB_0_DbLog_manuelle_Einträge.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/WB_1_openWB.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_0_KSEM.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1_API.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1_Speicher_1_ExternControl.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_2.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_2_API.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_3_Fake_WR.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_ctl.txt create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wirlpool_Shelly_2.5/.gitkeep create mode 100644 fhem/contrib/ch.eick/Photovoltaik/Wärmepumpe_Novelan_LAD9/.gitkeep create mode 100644 fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_EVU_Tibber.txt create mode 100644 fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_EVU_Tibber_connect.txt create mode 100644 fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_LogDBRep_EVU_Tibber_connect_SQL.txt create mode 100644 fhem/contrib/ch.eick/Strombörse/EVU_aWATTar/RAW_EVU_aWATTar.txt create mode 100644 fhem/contrib/ch.eick/Strombörse/EVU_aWATTar/RAW_LogDBRep_EVU_aWATTar_connect_SQL.txt diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wachmaschine_Shell_2.5/.gitkeep b/fhem/contrib/ch.eick/Photovoltaik/Wachmaschine_Shell_2.5/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_Node-Red_Flow.txt b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_Node-Red_Flow.txt new file mode 100644 index 000000000..e69de29bb diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_connect_bluelinky.txt b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_connect_bluelinky.txt new file mode 100644 index 000000000..c5639f1d1 --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_connect_bluelinky.txt @@ -0,0 +1,39 @@ +defmod Kia_connect MQTT2_DEVICE +attr Kia_connect DbLogExclude .* +attr Kia_connect DbLogInclude .* +attr Kia_connect IODev MQTT2_FHEM_Server +attr Kia_connect alias Kia_connect +attr Kia_connect autocreate 1 +attr Kia_connect devicetopic bluelinky +attr Kia_connect disable 0 +attr Kia_connect group PV Eigenverbrauch-Steuerung +attr Kia_connect icon car +attr Kia_connect readingList $DEVICETOPIC/status:.* { json2nameValue($EVENT) }\ +$DEVICETOPIC/location.* { json2nameValue($EVENT) }\ +$DEVICETOPIC/odometer:.* { json2nameValue($EVENT) }\ +$DEVICETOPIC/tripinfo:.* { json2nameValue($EVENT) }\ +$DEVICETOPIC/req_received:.* req_received\ +$DEVICETOPIC/req_active:.* req_active +attr Kia_connect room MQTT2_DEVICE,Strom->Photovoltaik +attr Kia_connect setList getOdometer req/$DEVICETOPIC/get_odometer get_odometer\ +getStatus req/$DEVICETOPIC/get_status get_status\ +getLocation req/$DEVICETOPIC/get_location get_location\ +getTripinfo req/$DEVICETOPIC/get_tripinfo\ +getAll req/$DEVICETOPIC/get_all get_all\ +setChargeTargetSoc req/$DEVICETOPIC/set_chargetargets\ +startCharge req/$DEVICETOPIC/start_charging start_charging\ +stopCharge req/$DEVICETOPIC/stop_charging stop_charging\ +stopClimate req/$DEVICETOPIC/stop_climate stop_climate\ +startClimate req/$DEVICETOPIC/start_climate\ +car_lock req/$DEVICETOPIC/car_lock car_lock\ +car_unlock req/$DEVICETOPIC/car_unlock car_unlock +attr Kia_connect sortby 402 +attr Kia_connect stateFormat req_active +attr Kia_connect userReadings atHomeStanding:location.* { ((abs(AttrVal("global","latitude",49.85) - ReadingsVal($NAME,"location_coord_lat",0)) <= 0.001) && (abs(AttrVal("global","longitude",8.49) - ReadingsVal($NAME,"location_coord_lon",0)) <= 0.001) && (ReadingsVal($NAME,"location_speed_value",1) == 0)) ? 'true' : 'false';;;; },\ +batSOC:status.* { ReadingsVal($NAME,"status_evStatus_batteryStatus",0);;;;},\ +connected:status.* { (ReadingsVal($NAME,"status_evStatus_batteryPlugin",0) != 0) ? 'true' : 'false';;;;},\ +charging:status.* { ReadingsVal($NAME,"status_evStatus_batteryCharge",'false');;;;},\ +targetSOC:status.* { ReadingsVal($NAME,"status_evStatus_reservChargeInfos_targetSOClist_2_targetSOClevel",0);;;;},\ +time2targetSOC:status.* { my $t = ReadingsVal($NAME,"status_evStatus_remainTime2_atc_value",1);;;; sprintf("%02d:%02d", $t/60%60, $t%60);;},\ +range:status.* { ReadingsVal($NAME,"status_evStatus_drvDistance_1_rangeByFuel_totalAvailableRange_value",0);;;;},\ +bat12v:status.* { ReadingsVal($NAME,"status_battery_batSoc",0);;;;} \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_eNiro_Steuerung.txt b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_eNiro_Steuerung.txt new file mode 100644 index 000000000..6d1088afe --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/Kia_eNiro_Steuerung.txt @@ -0,0 +1,782 @@ +defmod Kia_eNiro DOIF ################################################################################################################\ +## 1 Kia Connect Status Abfrage erfolgt mit MQTT2 ==> node-ret ==> Kia Connect\ +##\ +1_Status_getAll\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and [Kia_connect:req_active] eq "idle"\ + and\ + (\ + (\ + ( [+00:15] ## alle 15 Minuten\ + and ([Kia_connect:atHomeStanding] eq "true" ## wenn das Auto zuhause ist\ + and [Kia_connect:charging] eq "true" ## und es geladen wird\ + or [WB_1:lp_1_ChargeStat] eq "loading") ## Oder es ist bereits an der WB_1_lp_1\ + or [:58] and [?07:00-20:00] ## ansonsten nur jede Stunde\ + )\ + or\ + (\ + [WB_1:lp_1_PlugStat] eq "Plugged in" ## Auto scheint da zu sein, es fehlt jedoch der Status\ + and [Kia_connect:atHomeStanding] eq "false"\ + )\ + )\ + ## Es darf kein loop sein\ + and ::time_str2num(::ReadingsTimestamp("Kia_connect","req_active",0)) - ::time_str2num(::ReadingsTimestamp("Kia_connect","req_received",0)) > 5\ + and [Kia_connect:bat12v] > 40 ## aber die 12V Batterie sollte noch genügend Ladung haben\ + and [Heizung:opModeHotWater] ne "Aus" ## Wir sind nicht im Urlaub\ + )\ + or [$SELF:cmd_event] eq "set_cmd_1" ## Das reagiert auf den Aufruf mit "set cmd_*"\ + or [$SELF:ui_command_1] eq "Status_getAll" ## Hier wird das uiTable select ausgewertet\ + ) {\ + if( [$SELF:ui_command_1] eq "Status_getAll" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_before_1",[$SELF:ui_command_1]);;\ + }\ +\ + fhem_set("Kia_connect getAll");; ## beliebige Kommandos für diesen Block\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +2_Klima\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and [?Kia_connect:req_active] eq "idle"\ + and\ + ( [$SELF:ui_command_2] eq "stopClimate" ## Hier wird das uiTable select ausgewertet\ + or [$SELF:ui_command_2] eq "startHeating"\ + or [$SELF:ui_command_2] eq "startCooling"\ + or [WB_1:lp_1_PlugStat] eq "no Plug" ## Das Auto wurde von der WallBox getrennt\ + )\ + ) {\ +\ + if ( [$SELF:ui_command_before_2] eq "startHeating" ## Das Auto sollte nur geheizt werden\ + and\ + (\ + ( [$SELF:ui_command_2] eq "stopClimate" ## Das Heizen soll beendet werden\ + and [WB_1:lp_1_PlugStat] eq "Plugged in" \ + and [Kia_connect:atHomeStanding] eq "true"\ + )\ + or [WB_1:lp_1_PlugStat] eq "no Plug" ## Das Auto wurde von der WallBox getrennt\ + )\ + ) {\ +\ + fhem_set("WB_1 Lademodus Stop");; ## Die Wallbox wieder abschalte\ + if (AttrVal("$SELF","verbose",0) >= 3)\ + {Log 3, "$SELF 02_Klima : Lademodus Stop"};;\ + }\ +\ +\ + set_Reading("ui_command_before_2",[$SELF:ui_command_2]);; ## Die jetzige Auswahl merken\ +\ + if ([$SELF:ui_command_2] eq "startHeating") { ## Das Auto soll geheizt werden\ + my $airTemp_value = [Kia_connect:status_airTemp_value_target_Winter];;\ +\ + if ( [WB_1:lp_1_PlugStat] eq "Plugged in" ## Ist ein Auto angeschlossen\ + and [Kia_connect:atHomeStanding] eq "true") { ## Ist es unser Auto\ + fhem_set("WB_1 Lademodus SofortLaden");; ## Es ist besser für's Heizen die Wallbox zu aktivieren\ + if (AttrVal("$SELF","verbose",0) >= 3)\ + {Log 3, "$SELF 02_Klima : Lademodus SofortLaden"};;\ + }\ +\ + fhem_set('Kia_connect startClimate {"defrost": true, "windscreenHeating": true, "temperature": '.$airTemp_value.' , "unit": "C"}');;\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 02_Klima : startHeating $airTemp_value"};;\ + }\ + if ([$SELF:ui_command_2] eq "startCooling") { ## Das Auto soll gekühlt werden\ + my $airTemp_value = [Kia_connect:status_airTemp_value_target_Sommer];;\ +\ + if ( [WB_1:lp_1_PlugStat] eq "Plugged in" ## Ist ein Auto angeschlossen\ + and [Kia_connect:atHomeStanding] eq "true") { ## Ist es unser Auto\ + fhem_set("WB_1 Lademodus NurPV");; ## Im Sommer nur mit PV Überschuss kühlen\ + if (AttrVal("$SELF","verbose",0) >= 3)\ + {Log 3, "$SELF 02_Klima : Lademodus NurPV"};;\ + }\ +\ + fhem_set('Kia_connect startClimate {"defrost": false, "windscreenHeating": false, "temperature": '.$airTemp_value.' , "unit": "C"}');;\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 02_Klima : startCooling $airTemp_value"};;\ + }\ + if ([$SELF:ui_command_2] eq "stopClimate") { ## Die Klimatisierung manuell beenden\ + fhem_set("Kia_connect ".[$SELF:ui_command_2]);; ## Die Wallbox wurde bereits weiter oben abgeschaltet\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 02_Klima : stopClimate"};;\ + }\ + fhem_set("Abfall update");; ## Den Kalender für weitere Klimatisierungen abfragen\ +\ + set_Exec("wait_Status",20,'fhem_set("Kia_connect getAll")');; ## Starte Status Abfrage etwas verzögert\ +\ + set_Reading("ui_command_2","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +3_Laden\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and [Kia_connect:req_active] eq "idle"\ + and\ + ( [$SELF:ui_command_3] eq "setChargeTargetSoc" ## Hier wird das uiTable select ausgewertet\ + or [$SELF:ui_command_3] eq "startCharge"\ + or [$SELF:ui_command_3] eq "stopCharge"\ + )\ + ) {\ + set_Reading("ui_command_before_3",[$SELF:ui_command_3]);;\ +\ + if ([$SELF:ui_command_3] eq "setChargeTargetSoc") {\ + my $targetSOClist_1_targetSOClevel = [Kia_connect:status_evStatus_reservChargeInfos_targetSOClist_1_targetSOClevel_target];;\ + my $targetSOClist_2_targetSOClevel = [Kia_connect:status_evStatus_reservChargeInfos_targetSOClist_2_targetSOClevel_target];;\ + fhem_set("Kia_connect setChargeTargetSoc {\"fast\": ".$targetSOClist_1_targetSOClevel.", \"slow\": ".$targetSOClist_2_targetSOClevel."}");;\ + } else {\ + fhem_set("Kia_connect ".[$SELF:ui_command_3]);; ## beliebige Kommandos für diesen Block\ + }\ + set_Exec("wait_Status",5,'fhem_set("Kia_connect getAll")');; ## Starte Status Abfrage etwas verzögert\ + set_Reading("ui_command_3","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +4_Klima_timer_heizen\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ( [[Abfall_Abfuhr:Kiaheizen_connect_time]] ## Prüfe den Kalender Eintrag\ + and [Abfall_Abfuhr:Kiaheizen_connect_date] eq $ymd ## ist es heute?\ + )\ + or\ + ( [$SELF:ui_timer_mode] eq "heizen" ## Timer zum Heizen aktiv?\ + and [[$SELF:ui_timer_Start]] ## ist es soweit?\ + )\ + )\ + ) {\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 04_Klima_timer : startHeating"};;\ + set_Reading("ui_timer_mode","Aus");; ## Schalte die Timer Funktion ab\ + set_Reading("ui_command_2","startHeating");; ## Es soll geheizt werden\ + fhem_set("$SELF 2_Klima");; ## Aktiviere das Heizen\ +\ + }\ +}\ +\ +5_Klima_timer_kuehlen\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ( [[Abfall_Abfuhr:Kiakuehlen_connect_time]] ## Prüfe den Kalender Eintrag\ + and [Abfall_Abfuhr:Kiakuehlen_connect_date] eq $ymd ## ist es heute?\ + )\ + or\ + ( [$SELF:ui_timer_mode] eq "kuehlen" ## Timer zum Kühler aktiv?\ + and [[$SELF:ui_timer_Start]] ## ist es soweit?\ + )\ + )\ + ) {\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 05_Klima_timer : startCooling"};;\ + set_Reading("ui_timer_mode","Aus");; ## Schalte die Timer Funktion ab\ + set_Reading("ui_command_2","startCooling");; ## Es soll gekühlt werden\ + fhem_set("$SELF 2_Klima");; ## Aktiviere das Kühlen\ +\ + }\ +}\ +\ +6_Auf_Zu\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and [Kia_connect:req_active] eq "idle"\ + and\ + ( [$SELF:ui_command_1] eq "car_lock" ## Hier wird das uiTable select ausgewertet\ + or [$SELF:ui_command_1] eq "car_unlock"\ + )\ + ) {\ + set_Reading("ui_command_before_1",[$SELF:ui_command_1]);;\ +\ + fhem_set("Kia_connect ".[$SELF:ui_command_1]);;\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 06_Auf_Zu : ".[$SELF:ui_command_1]};;\ +\ + set_Exec("wait_Status",20,'fhem_set("Kia_connect getAll")');; ## Starte Status Abfrage etwas verzögert\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +7_WB_1_lp_1\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ( [$SELF:ui_command_4] eq "SofortLaden" ## Hier wird das uiTable select ausgewertet\ + or [$SELF:ui_command_4] eq "MinPV"\ + or [$SELF:ui_command_4] eq "NurPV"\ + or [$SELF:ui_command_4] eq "Stop"\ + or [$SELF:ui_command_4] eq "Standby"\ + or [$SELF:ui_command_4] eq "Vorrang_EV"\ + or [$SELF:ui_command_4] eq "Vorrang_Bat"\ + or [$SELF:WB_1_lp_1_current_soll]\ + )\ + and [$SELF:ui_command_4] ne "12_WB_1_lp_1_Sofortladen_ende_limit"\ + and [$SELF:ui_command_4] ne "12_WB_1_Backup"\ + and [$SELF:ui_command_4] ne "10_70_beachten"\ + and [$SELF:ui_command_4] ne "10_70_beachten_ende"\ + and [$SELF:ui_command_4] ne "11_Ladebasis_berechnen"\ + and [$SELF:ui_command_4] ne "12_Stromboerse"\ +\ + ) {\ + set_Reading("ui_command_before_4",[?$SELF:ui_command_4]);;\ +\ + ## Die Ladebegrenzung für's SofortLaden wurde geändert\ + if ( [?$SELF:ui_command_4] eq "---" or [?$SELF:ui_command_4] eq "SofortLaden") {\ + fhem_set("WB_1 lp_1_current ".[?$SELF:WB_1_lp_1_current_soll]);; ## setze den neuen Sollwert\ + set_Reading("ui_command_before_4","Ladebegrenzung");;\ + set_Reading("ui_command_4","SofortLaden");; ## starte als nächstes das SofortLaden\ +# if (AttrVal("$SELF","verbose",0) >= 0)\ +# {Log 3, "$SELF 07_WB_1_lp_1 : lp_1_current ".[?$SELF:WB_1_lp_1_current_soll]};;\ + }\ + if ([?$SELF:ui_command_4] eq "NurPV" or [?$SELF:ui_command_4] eq "Stop") {\ + set_Reading("WB_1_lp_1_current_soll","32");; ## reset des Leistungsbegrenzung\ + fhem_set("WB_1 lp_1_current ".[?$SELF:WB_1_lp_1_current_soll]);; ## setze den neuen Sollwert\ +# if (AttrVal("$SELF","verbose",0) >= 0)\ +# {Log 3, "$SELF 07_WB_1_lp_1 : lp_1_current ".[?$SELF:WB_1_lp_1_current_soll]};;\ + }\ + if ([?$SELF:ui_command_4] eq "Vorrang_Bat" or [?$SELF:ui_command_4] eq "Vorrang_EV") {\ + if ([$SELF:ui_command_4] eq "Vorrang_EV") {\ + fhem_set("WB_1 priorityModeEVBattery 1");;\ + } else {\ + fhem_set("WB_1 priorityModeEVBattery 0");;\ + }\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 07_WB_1_lp_1 : ".[?$SELF:ui_command_4]};;\ + } else {\ + fhem_set("WB_1 Lademodus ".[?$SELF:ui_command_4]);;\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 07_WB_1_lp_1 : Lademodus ".[?$SELF:ui_command_4]};;\ + }\ +\ + set_Reading("ui_command_4","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +12_WB_1_lp_1_Sofortladen_ende_limit\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ( ( [WB_1:ChargeMode] eq "SofortLaden" ## LP1 ist im Sofortladen und Limitiert\ + and [$SELF:WB_1_lp_1_current_soll] < 32\ + and [WR_1:Total_Active_P_EM] > 500 ## Hier beginnt der Netzbezug\ + )\ + or [$SELF:ui_command_4] eq "12_WB_1_lp_1_Sofortladen_ende_limit"\ + )\ + ) {\ + fhem_set("WB_1 Lademodus NurPV");; ## Das limitierte SofortLaden beenden und mit NurPV weiter laden\ + set_Reading("WB_1_lp_1_current_soll","32");; ## reset der Ladebegrenzung, damit es nicht vergessen wird\ + fhem_set("WB_1 lp_1_current ".[$SELF:WB_1_lp_1_current_soll]);; ## setze den neuen Sollwert\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 12_WB_1_lp_1 : Lademodus NurPV"};;\ +\ + set_Reading("ui_command_4","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +9_WB_1_Zaehler_Statistiken\ +{if( !([$SELF:state] eq "off") and ## DOIF enabled\ + [00:01]\ + ) {\ + fhem("setreading WB_1 lp_1_kWhCounter_init_Day ".[WB_1:lp_1_kWhCounter]);;\ + fhem("setreading WB_1 lp_2_kWhCounter_init_Day ".[WB_1:lp_2_kWhCounter]);;\ +\ + if ($mday eq 1)\ + {\ + fhem("setreading WB_1 lp_1_kWhCounter_init_Month ".[WB_1:lp_1_kWhCounter]);;\ + fhem("setreading WB_1 lp_2_kWhCounter_init_Month ".[WB_1:lp_2_kWhCounter]);;\ +\ + if ($yday eq 0)\ + {\ + fhem("setreading WB_1 lp_1_kWhCounter_init_Year ".[WB_1:lp_1_kWhCounter]);;\ + fhem("setreading WB_1 lp_2_kWhCounter_init_Year ".[WB_1:lp_2_kWhCounter]);;\ + }\ + }\ + }\ +}\ +\ +10_70_beachten\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ( [$SELF:ui_70_basis] eq "70%_An" ## Es soll im Mittagshoch geladen werden\ + and [[WR_ctl:Yield_fc0_middayhigh_start]-[WR_ctl:Yield_fc0_middayhigh_stop]] ## Innerhalb diese Zeitraums\ + and\ + ( \ + [WB_1:ChargeMode] eq "Stop" ## Noch ist kein Lademodus definiert\ + and [WB_1:lp_1_PlugStat] eq "Plugged in" ## Das Auto ist verbunden\ +\ + or\ + (\ + [WB_1:ChargeMode] eq "NurPV" ## Noch ist kein Lademodus definiert\ + and\ + ( [WB_1:lp_1_ChargeStat] eq "loading" ## Das Auto ist verbunden\ + or [WB_1:lp_1_PlugStat] eq "Plugged in"\ + )\ + and ## Wenn ein stark Verbraucher läuft\ + ( [StromZaehler_Heizung:SMAEM1901401955_Bezug_Wirkleistung] ## LWWP\ + or [shelly02:power_0] ## Pool \ + or [shelly05:power_0] ## Brunnen\ + or [shelly03:power] ## Waschmaschine\ + )\ + )\ + )\ + and [$SELF:ui_command_4] eq "---" \ + )\ + or\ + [$SELF:ui_command_4] eq "10_70_beachten" ## 70 % beachten neu berechnen\ + )\ + ) {\ +\ + my $Starkverbraucher = ::round(\ + ReadingsVal("StromZaehler_Heizung","SMAEM1901401955_Bezug_Wirkleistung",0)\ + + ReadingsVal("shelly02","power_0",0)\ + + ReadingsVal("shelly05","power_0",0)\ + + ReadingsVal("shelly03","power",0) ,0) ;;\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 70 % berechnen : Starkverbraucher $Starkverbraucher"};;\ +\ + if ($Starkverbraucher < 200) {\ + $Starkverbraucher = 0;;\ + Log 3, "$SELF 70 % berechnen : Starkverbraucher $Starkverbraucher";;\ + } ;;\ +\ + my $tmp = ::round( ([?$SELF:WB_1_nurpv70dynw_soll] - $Starkverbraucher ) /100 ,0) *100 ;;\ +\ + if ($tmp < [?$SELF:WB_1_nurpv70dynw_soll]) {\ +# $tmp = [?$SELF:WB_1_nurpv70dynw_soll];;\ + if (AttrVal("$SELF","verbose",4) >= 0)\ + {Log 3, "$SELF 70 % berechnen : Starkverbraucher laufen, dynamische Basis reduziert auf $tmp"};;\ + } ;;\ +\ + set_Reading("WB_1_nurpv70dynw",$tmp);; ## Momentanen Wert merken\ + fhem("set WB_1 nurpv70dynw ".$tmp);; ## 70% Basis in der WB setzen\ +\ + if (AttrVal("$SELF","verbose",0) >= 0) {\ + Log 3, "$SELF 70 % berechnen : basis ".[?$SELF:WB_1_nurpv70dynw_soll]." dynw $tmp";;\ + };;\ +\ + if ( ReadingsVal("$SELF","ui_70_basis","") eq "70%_An" ## Soll 70%_beachten verwendet werden?\ + and\ + ( ReadingsVal("WB_1","bool70PVDynStatus",0) eq "0" ## 70% beachten ist aus\ + or ReadingsVal("WB_1","nurpv70dynact",0) eq "0" ) ## 70% Konfiguration ist nicht aktiv\ + ) {\ +\ + fhem("set WB_1 nurpv70dynact 1");; ## 70% beachten in der Konfiguration aktivieren\ + fhem("set WB_1 NurPV70Status 1");; ## 70% beachten einschalten\ + fhem("set WB_1 Lademodus NurPV");; ## Das wird nur im PV Laden Modus verwendet\ + fhem_set("WB_1 priorityModeEVBattery 1");; ## Das EV soll vor dem Speicher bevorzugt werden\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 70 % berechnen : aktiviert"};;\ + } ;;\ +\ + if ([?$SELF:ui_command_4] eq "10_70_beachten")\ + {set_Reading("ui_command_4","---")};; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +\ +10_70_beachten_auto\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ( [$SELF:ui_70_basis] eq "70%_Aus" ## Es soll im Mittagshoch geladen werden\ + and [WR_ctl:Yield_fc0_middayhigh] == 1 ## Es gibt noch ein Mittagshoch\ + and [WB_1:ChargeMode] eq "Stop" ## Noch ist kein Lademodus definiert\ + and [WB_1:lp_1_PlugStat] eq "Plugged in" ## Das Auto ist verbunden\ +## and ::round((time - ::time_str2num(::ReadingsTimestamp("$SELF","ui_70_basis",""))) /3600 ,0) > 12 ## gestern war es auch aktiviert\ + and time +2 < ## und jetzt sind noch 2 h möglich\ + ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[WR_ctl:Yield_fc0_middayhigh_stop].":00")\ + and [$SELF:ui_command_4] eq "---" \ + )\ + or\ + [$SELF:ui_command_4] eq "10_70_beachten_auto" ## 70 % beachten nochmal aktivieren\ + )\ + ) {\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 70%_beachten_auto : automatische Aktivierung";;\ + Log 3, "$SELF 70%_beachten_auto : bisher ".[$SELF:ui_70_basis];;\ + Log 3, "$SELF 70%_beachten_auto : letzter Lauf vor ".::round((time - ::time_str2num(::ReadingsTimestamp("$SELF","ui_70_basis",""))) /3600 ,0)." h";;\ + Log 3, "$SELF 70%_beachten_auto : bleibt noch auf ".[WB_1:ChargeMode];;\ + };;\ +## set_Reading("ui_70_basis","70%_An");; ## Die 70% Regelung aktivieren\ + fhem("setreading $SELF ui_70_basis 70%_An");;\ +\ + if ([?$SELF:ui_command_4] eq "10_70_beachten_auto")\ + {set_Reading("ui_command_4","---")};; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +\ +10_70_beachten_ende\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ( [$SELF:ui_70_basis] eq "70%_An" ## Es soll im Mittagshoch geladen werden\ + and\ + [[WR_ctl:Yield_fc0_middayhigh_stop]-00:00] ## Die Ladezeit ist rum, oder nicht gesetzt\ + and [$SELF:ui_command_4] eq "---" \ + )\ + or\ + [$SELF:ui_command_4] eq "10_70_beachten_ende" ## 70 % beachten manuell beenden\ + )\ + ) {\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF 70%_beachten_ende : deaktiviert";;\ + Log 3, "$SELF 70%_beachten_ende : ".[$SELF:ui_70_basis];;\ + Log 3, "$SELF 70%_beachten_ende : ".[WR_ctl:Yield_fc0_middayhigh];;\ + Log 3, "$SELF 70%_beachten_ende : ".[WR_ctl:Yield_fc0_middayhigh_stop];;\ + Log 3, "$SELF 70%_beachten_ende : ".[WB_1:ChargeMode];;\ + Log 3, "$SELF 70%_beachten_ende : ".[WB_1:lp_1_ChargeStat];;\ + Log 3, "$SELF 70%_beachten_ende : ".[$SELF:ui_command_4];;\ + };;\ + set_Reading("ui_70_basis","70%_Aus");; ## Den Button zurück setzen\ +\ + if ([?$SELF:ui_command_4] eq "10_70_beachten_ende") { ## wenn es manuell umgeschaltet wurde\ + fhem("set WB_1 Lademodus NurPV") ## auf NurPV zurückfallen\ + }\ + else { ## geschiet es automatisch, ist die Ladezeit abgelaufen\ + fhem("set WB_1 Lademodus Stop") ## dann auf Stop gehen (und bis morgen warten)\ + };;\ + fhem("set WB_1 NurPV70Status 0");; ## 70% beachten abschalten\ + fhem_set("WB_1 priorityModeEVBattery 0");; ## Wieder den Hausspeicher bevorzugen\ +\ + if ([?$SELF:ui_command_4] eq "10_70_beachten_ende")\ + {set_Reading("ui_command_4","---")};; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +11_Ladebasis_berechnen\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + [06:00] ## jeden Morgen einmal berechnen\ + or\ + [$SELF:ui_70_basis] eq "70%_Aus" ## oder wenn es abgeschaltet wurde\ + )\ + or\ + [$SELF:ui_command_4] eq "11_Ladebasis_berechnen" ## \ + ) {\ +\ + if (time < ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_start].":00") ) {\ + if (AttrVal("$SELF","verbose",0) >= 0) {Log 3, "$SELF Ladebasis_berechnen : Ladezeit noch nicht erreicht"}\ + } else {\ + if (time < ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_stop].":00") ) {\ + if (AttrVal("$SELF","verbose",0) >= 0) {Log 3, "$SELF Ladebasis_berechnen : Ladezeit läuft"}\ + } else {\ + if (AttrVal("$SELF","verbose",0) >= 0) {Log 3, "$SELF Ladebasis_berechnen : Ladezeit beendet"}\ + }\ + }\ +\ + if ( [?$SELF:ui_70_basis] eq "70%_An"\ + and [?$SELF:ui_command_4] ne "11_Ladebasis_berechnen") { ## Nicht beenden, wenn es manuell geprüft wird\ + fhem("set WB_1 NurPV70Status 0");; ## Das 70%_beachten erstmal stoppen\ + set_Reading("ui_70_basis","70%_Aus");; ## Den Button zurück setzen\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF Ladebasis_berechnen : deaktiviert"};;\ + }\ +\ + ## Wieviel kWh würden ins E-Auto rein gehen\ + my $delta_wh = ::round( (64 * ([?Kia_connect:targetSOC] - [?Kia_connect:batSOC]) / 100 *1000 *[?$SELF:WB_1_nurpv70dynw_Faktor]) , 0) ;;\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF Ladebasis_berechnen : delta_wh $delta_wh"};;\ +\ + if ([?WR_ctl:Yield_fc0_middayhigh] == 1) {\ + ## Wieviele Stunden ist das Mittagshoch\ + my $Mittagshoch_h = ( ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_stop].":00")\ + - ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_start].":00")) / 3600 ;;\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF Ladebasis_berechnen : Mittagshoch_h $Mittagshoch_h"};;\ + ## Wie wäre die durchschnittliche Ladeleistung\ + my $charge_Power_wh = ::round( $delta_wh / $Mittagshoch_h ,0);; ## Ca. Leistung pro Stunde als Mittelwert\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF Ladebasis_berechnen : charge_Power_wh $charge_Power_wh"};;\ +\ + my $fc_Power_wh = 0;;\ + my $start = substr([?WR_ctl:Yield_fc0_middayhigh_start],0,2);; ## Start Stunde als Zähler\ +\ + for (my $i = $start;; $i < $start+$Mittagshoch_h;; $i++) {\ + $fc_Power_wh += ReadingsVal("WR_ctl","Yield_fc0_".sprintf("%02d",$i),0);; ## Summe der Prognose Leistungen\ + }\ +\ + Log 3, "$SELF Ladebasis_berechnen : fc_Power_wh $fc_Power_wh";; ## Leistungsprognose\ + my $base_70 = ::round(($fc_Power_wh/$Mittagshoch_h - $charge_Power_wh) /100 ,0) *100;; ## Nur volle 100 Watt\ +\ + if ( $base_70 > 10000 ) {\ + $base_70 = ::round((9000 - $charge_Power_wh) /100 ,0) *100;;\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF Ladebasis_berechnen : Der Forecast Übersteigt die maximale 70% Regelung"};;\ + }\ +\ + if ($base_70 < 2000) { ## das ist das openWB minimum\ +# $base_70 = [?$SELF:WB_1_nurpv70dynw_soll];;\ + $base_70 = 2000;;\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF Ladebasis_berechnen : Das Auto kann an diesem Tag nicht mit 70% Regelung voll geladen werden"};;\ + }\ +\ + set_Reading("WB_1_nurpv70dynw_soll",$base_70);; ## 70 % Basis für die Wallbox\ +\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF Ladebasis_berechnen : 70% Basis $base_70"};;\ + }\ +\ + if ([?$SELF:ui_command_4] eq "11_Ladebasis_berechnen")\ + {set_Reading("ui_command_4","---")};; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 12 Stromboerse\ +##\ +12_Stromboerse\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (( [WR_ctl:Yield_fc0_day] < [WR_1_Speicher_1_ExternControl:SpeicherMinSOC_fc1_Limit] ## Im Herbst/Winter ist wenig zu erwarten\ + and [WB_1:lp_1_PlugStat] eq "Plugged in" \ +# and [Kia_connect:atHomeStanding] eq "true" ## wenn das Auto zuhause ist\ +\ + and [$SELF:SpeicherStromboerse] eq "Tibber" ## Soll Tibber verwendet werden?\ + and [EVU_Tibber_connect:fc0_trigger] ## Wurde der Trigger geändert\ + )\ + or [$SELF:ui_command_4] eq "12_Stromboerse" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if ([?EVU_Tibber_connect:fc0_trigger] eq "on") {\ + set_Reading("SpeicherTriggerLaden","An");;\ +\ + fhem_set("WB_1 Lademodus SofortLaden");;\ + if (AttrVal("$SELF","verbose",0) >= 3)\ + {Log 3, "$SELF 12_Stromboerse : Lademodus SofortLaden"};;\ +\ + } else {\ + set_Reading("SpeicherTriggerLaden","Aus");;\ +\ + fhem_set("WB_1 Lademodus Stop");;\ + if (AttrVal("$SELF","verbose",0) >= 3)\ + {Log 3, "$SELF 12_Stromboerse : Lademodus Stop"};;\ +\ + }\ +\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF 12_Stromboerse : ".[EVU_Tibber_connect:fc0_trigger]." by ".[$SELF:SpeicherStromboerse]};;\ +\ + set_Reading("ui_command_4","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 13 WB_1_Backup\ +##\ +13_WB_1_Backup\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ( [02:30]\ + and $mday == 1 ## \ + )\ + or\ + [$SELF:ui_command_4] eq "13_WB_1_Backup" ## \ + ) {\ + fhem("setreading $SELF backup running");;\ + my $openwbBackupURL = AttrVal("$SELF", "openWB_lp1_Url", "http://openwb") . "/openWB/web/settings/backup.php";;\ + ::HttpUtils_NonblockingGet( { \ + url=>$openwbBackupURL, timeout=>120, callback=>sub() {\ + my ($hash, $err, $ret) = @_;;\ + if ($err || ($ret !~ "Backup-Datei backup.tar.gz erfolgreich erstellt.")) {\ + fhem("setreading $SELF backup error creating backup: $err $ret");;\ + } else {\ + fhem("setreading $SELF backup downloading");; \ + my $openwbDownloadURL = AttrVal("$SELF", "openWB_lp1_Url", "http://openwb") . "/openWB/web/backup/backup.tar.gz";;\ + my $BackupDir = AttrVal("$SELF", "openWB_BackupDir", "././www");;\ + ::HttpUtils_NonblockingGet({ \ + url=>$openwbDownloadURL, timeout=>120, callback=>sub() {\ + my ($hash, $err, $data) = @_;;\ + my $filename = "$BackupDir/".sprintf("%d%02d%02d",$year,$month,$mday)."_openwb_lp1_backup.tar.gz";;\ + if(open(FH, ">$filename")) {\ + print FH $data;;\ + close(FH);; \ + fhem("setreading $SELF backup $filename");;\ + } else {\ + fhem("setreading $SELF backup error downloading $filename");;\ + }\ + } # End URL=>\ + });; # End HttpUtils_NonblockingGet\ + }\ + } # End URL=>\ + });; # End HttpUtils_NonblockingGet\ +\ + if ([?$SELF:ui_command_4] eq "12_WB_1_Backup")\ + {set_Reading("ui_command_4","---")};; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ + +attr Kia_eNiro userattr openWB_lp1_Url openWB_lp2_Url openWB_BackupDir +attr Kia_eNiro DbLogExclude .* +attr Kia_eNiro disable 0 +attr Kia_eNiro group PV Eigenverbrauch-Steuerung +attr Kia_eNiro icon car +attr Kia_eNiro openWB_BackupDir ./backup +attr Kia_eNiro openWB_lp1_Url http://192.168.178.61 +attr Kia_eNiro openWB_lp2_Url http://192.168.178.62 +attr Kia_eNiro room 2_PV_Steuerung,Strom->Photovoltaik +attr Kia_eNiro sortby 401 +attr Kia_eNiro uiTable {\ +package ui_Table;;\ +## $TR{0} = "style='color:yellow;;text-align:left;;font-weight:bold;;font-size:18px'";; ## Reihe 0 für Überschrift\ + $TABLE = "style='width:100%;;'";;\ +\ + $TD{0..9}{0} = "align='center' style='font-size:16px;;border-right-style:solid;;border-color:darkgreen;;border-right-width:2px;;width:26%'";;\ +\ + $TD{0..9}{1} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ + $TD{0..9}{2..4} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ + $TD{0..9}{5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ +\ +sub FUNC_batt {\ + my($val)=@_;;\ + my $ret="position:absolute;;left:".(90*$val/100)."px;;width:90px;;height:20px;;background:linear-gradient( to right,#F8F8E0 ".(90-(90*$val/100))."px,rgba(0,0,0,0) ".(90-(90*$val/100))."px);;";;\ + return $ret;;\ + }\ +sub FUNC_Status {\ + my($value, $min, $colorMin, $statusMin, $colorMiddel, $statusMiddle, $max, $colorMax, $statusMax)=@_;;\ + my $ret = ($value < $min)? ''.$statusMin.'' : ($value > $max)? ''.$statusMax.'' : ''.$statusMiddle.'';;\ + return $ret;;\ + }\ +sub FUNC_Status_Laden {\ + my($car)=@_;;\ + my $charge = (::ReadingsVal($car,"charging","false") eq "true");;\ + my $athome = (::ReadingsVal($car,"atHomeStanding","false") eq "true");;\ + my $chargeathome = ($charge && $athome);;\ + my $connectedathome = ($athome && ::ReadingsVal($car,"connected","false") eq "true");;\ +\ + my $ret = ($chargeathome ? "lädt zu Hause" : ($connectedathome ? "angeschlossen zu Hause" : ($athome ? "zu Hause" : ($charge ? "Lädt auswärts" : "unterwegs"))));;\ + return $ret;;\ + }\ +sub FUNC_tire {\ + my($car)=@_;;\ + my $ret = 'Reifendruck okay';;\ +\ + if (::ReadingsVal($car,"status_tirePressureLamp_tirePressureLampAll","1") != 0) {\ + my $VL = (::ReadingsVal($car,"status_tirePressureLamp_tirePressureLampFL","1") eq "0")?0:1;;\ + my $HL = (::ReadingsVal($car,"status_tirePressureLamp_tirePressureLampRL","1") eq "0")?0:1;;\ + my $VR = (::ReadingsVal($car,"status_tirePressureLamp_tirePressureLampFR","1") eq "0")?0:1;;\ + my $HR = (::ReadingsVal($car,"status_tirePressureLamp_tirePressureLampRR","1") eq "0")?0:1;;\ + $ret = 'Reifen Störung
';;\ + if ($VL == 1){$ret.=' /VL'};;\ + if ($VR == 1){$ret.=' /VR'};;\ + if ($HL == 1){$ret.=' /HL'};;\ + if ($HR == 1){$ret.=' /HR'};;\ + $ret = $ret.'
';;\ + }\ + return $ret;;\ + }\ +sub FUNC_door {\ + my($car)=@_;;\ + my $ret = 'Türen okay
';;\ +\ + if (::ReadingsVal($car,"status_doorLock","false") ne "true") {\ + my $VL = (::ReadingsVal($car,"status_doorOpen_frontLeft",1) == 0)?0:1;;\ + my $HL = (::ReadingsVal($car,"status_doorOpen_backLeft",1) == 0)?0:1;;\ + my $VR = (::ReadingsVal($car,"status_doorOpen_frontRight",1) == 0)?0:1;;\ + my $HR = (::ReadingsVal($car,"status_doorOpen_backRight",1) == 0)?0:1;;\ + $ret = 'Tür offen
';;\ + if ($VL == 1){$ret.=' /VL'};;\ + if ($VR == 1){$ret.=' /VR'};;\ + if ($HL == 1){$ret.=' /HL'};;\ + if ($HR == 1){$ret.=' /HR'};;\ + $ret = $ret.'
';;\ + }\ + if (::ReadingsVal($car,"status_trunkOpen","true") eq "true") {\ + $ret.=' Kofferraum offen';;\ + }\ + if (::ReadingsVal($car,"status_hoodOpen","true") eq "true") {\ + $ret.=' Motorhaube offen';;\ + }\ + return $ret;;\ + }\ +\ +}\ +\ +"$SELF"|\ +"Kommando ".::ReadingsTimestamp("Kia_connect","status_time","")."
Auswahl / Kommunikation / Tacho / Info Status
"|\ +widget([$SELF:ui_command_1],"uzsuDropDown,---,Status_getAll,car_lock,car_unlock")|\ +(([Kia_connect:req_active] eq "idle")?'idle' : ''.[Kia_connect:req_active].'')|\ +(([Kia_connect:odometer_value] > [$SELF:ui_Inspektion] - 2000)?'Inspektion
'. ::round([Kia_connect:odometer_value],0).' km
' : ::round([Kia_connect:odometer_value],0)." km")|\ +FUNC_Status_Laden("Kia_connect")\ +\ +|\ +"Strombörse
Auswahl / Ladefenster / Trigger Status
" |\ +widget([$SELF:SpeicherStromboerse],"uzsuDropDown,Aus,Tibber") | \ +"Trigger fc0

".Format("trigger_0")|\ +"Trigger fc1

".Format("trigger_1")|\ +[EVU_Tibber_connect:fc0_trigger] \ +\ +|\ +"Accu
Steuerung / Target Soc / Accu Status
"|\ +widget([$SELF:ui_command_3],"uzsuDropDown,---,setChargeTargetSoc,stopCharge,startCharge")|\ +widget([Kia_connect:status_evStatus_reservChargeInfos_targetSOClist_2_targetSOClevel_target],"selectnumbers,50,10,100,0,lin")." % AC
".widget([Kia_connect:status_evStatus_reservChargeInfos_targetSOClist_1_targetSOClevel_target],"selectnumbers,50,10,100,0,lin")." % DC"|\ +""|\ +FUNC_Status([Kia_connect:range],150,"red",[Kia_connect:range],"orange",[Kia_connect:range],250,"green",[Kia_connect:range])." km"."
".STY(" ",FUNC_batt([Kia_connect:batSOC])).STY(::round([Kia_connect:batSOC],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."
"\ +\ +|"Komfort
Timer / Klima / Reifen / Türen / Accu Status 12V
"|\ +widget([$SELF:ui_timer_mode],"uzsuDropDown,Aus,heizen,kuehlen").widget([$SELF:ui_timer_Start],"time")|\ +((::ReadingsVal("Abfall_Abfuhr","Kiaheizen_days",0) != 0)?"Klimatisierung
".[Abfall_Abfuhr:Kiaheizen_connect_date]." ".[Abfall_Abfuhr:Kiaheizen_connect_time]:(([$SELF:ui_timer_mode] ne "Aus")?"Klimatisierung
".[$SELF:timer_04_c04]:""))|\ +(FUNC_tire("Kia_connect")."
".FUNC_door("Kia_connect"))|\ +"12 V
".STY(" ",FUNC_batt([Kia_connect:bat12v])).STY(::round([Kia_connect:bat12v],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."
"\ +\ +|"
Auswahl / Temperatur / Klima Status / Temperatur innen
"|\ +widget([$SELF:ui_command_2],"uzsuDropDown,---,stopClimate,startHeating,startCooling")|\ +"Heat".widget([Kia_connect:status_airTemp_value_target_Winter],"selectnumbers,20,1,27,0,lin")."°C
Cool".widget([Kia_connect:status_airTemp_value_target_Sommer],"selectnumbers,16,1,25,0,lin")."°C"|\ +(([Kia_connect:status_airCtrlOn] eq "true")?'Klima läuft':'Klima aus')."
".(([Kia_connect:status_defrost] eq "true")?'Defrost ein':'Defrost aus')|\ +"Aktuell
".[Kia_connect:status_airTemp_value]."°C"\ +\ +"Link: WB_1_lp1"|\ +"WallBox
Lademodus / Lade Limits / Info Status / Leistung & Ladezeit
"|\ +[WB_1:ChargeMode]."
". widget([$SELF:ui_command_4],"uzsuDropDown,---,SofortLaden,MinPV,NurPV,Stop,Standby,Vorrang_EV,Vorrang_Bat,10_70_beachten,10_70_beachten_auto,10_70_beachten_ende,11_Ladebasis_berechnen,12_WB_1_lp_1_Sofortladen_ende_limit,12_Stromboerse,13_WB_1_Backup"). widget([$SELF:ui_70_basis],"uzsuToggle,70%_Aus,70%_An")|\ +"SofortLaden
limit".widget([$SELF:WB_1_lp_1_current_soll],"selectnumbers,6,1,32,0,lin")."A
70%_fkt ".widget([$SELF:WB_1_nurpv70dynw_Faktor],"select,0.5,0.6,0.7,0.8,0.9,1,1.1,1.2,1.3,1.4,1.5")."
".(([WR_ctl:Yield_fc0_middayhigh] == 0)? "Heute kein 70% Laden möglich":([$SELF:e_Kia_eNiro_PV_ui_command_4] eq "Stop" and [$SELF:ui_70_basis] eq "70%_An")?"70%_Base ".[$SELF:WB_1_nurpv70dynw_soll]." W
".[?WR_ctl:Yield_fc0_middayhigh_start]." - ".[?WR_ctl:Yield_fc0_middayhigh_stop]:([$SELF:ui_70_basis] eq "70%_An")?"70%_Base ".[$SELF:WB_1_nurpv70dynw_soll]."
sofort - ".[?WR_ctl:Yield_fc0_middayhigh_stop]:"70% Laden
heute - ".[?WR_ctl:Yield_fc0_middayhigh_stop])|\ +[WB_1:lp_1_PlugStat]." ".[WB_1:lp_1_ChargeStat]|\ +[WB_1:lp_1_countPhasesInUse]."P ".[WB_1:lp_1_AConfigured]."A
".[WB_1:lp_1_W]." W
".[WB_1:lp_1_TimeRemaining]\ +\ +|\ +"Statistik
Ladeleistung inklusive externe Ladung
"|\ +""|\ +"heute/letztes
".sprintf("%5.2f / %5.2f",::ReadingsVal("WB_1","lp_1_kWhDailyCharged",0),::ReadingsVal("WB_1","lp_1_kWhChargedSincePlugged",0))|\ +"Monat/Vormonat
".sprintf("%03d / %03d",::round(::ReadingsVal("WB_1","lp_1_kWhCounter_Month",0)+::ReadingsVal("WB_0","Kia_eNiro_kWhCounter_Month",0),0),::ReadingsVal("LogDBRep_Statistic_previous_Month","WB_1_lp_1_kWhCounter_Month",0)+::ReadingsVal("LogDBRep_Statistic_previous_Month","WB_0_Kia_eNiro_kWhCounter_Month",0))|\ +"Jahr/Vorjahr
".sprintf("%04d / %04d",::ReadingsVal("WB_1","lp_1_kWhCounter_Year",0)+::ReadingsVal("WB_0","Kia_eNiro_kWhCounter_Year",0),::ReadingsVal("LogDBRep_Statistic_previous_Year","WB_1_lp_1_kWhCounter_Year",0)+::ReadingsVal("LogDBRep_Statistic_previous_Year","WB_0_Kia_eNiro_kWhCounter_Year",0)) +attr Kia_eNiro verbose 3 + +setstate Kia_eNiro 2024-01-15 18:37:57 SpeicherStromboerse Aus +setstate Kia_eNiro 2024-01-15 18:37:24 SpeicherTriggerLaden Aus +setstate Kia_eNiro 2024-01-19 16:29:55 WB_1_lp_1_current_soll 32 +setstate Kia_eNiro 2023-09-25 15:57:51 WB_1_nurpv70dynw 1100 +setstate Kia_eNiro 2023-09-11 17:03:42 WB_1_nurpv70dynw_Faktor 1 +setstate Kia_eNiro 2023-10-01 06:00:00 WB_1_nurpv70dynw_soll 8700 +setstate Kia_eNiro 2022-03-22 13:28:12 WR_1_Speicher_1_ExternControl_smart_laden_before --- +setstate Kia_eNiro 2023-09-25 16:00:00 ui_70_basis 70%_Aus +setstate Kia_eNiro 2023-08-14 11:40:13 ui_Inspektion 41500 +setstate Kia_eNiro 2024-01-24 15:58:00 ui_command_1 --- +setstate Kia_eNiro 2024-01-20 09:38:30 ui_command_2 --- +setstate Kia_eNiro 2024-01-19 16:29:40 ui_command_3 --- +setstate Kia_eNiro 2024-01-19 19:55:43 ui_command_4 --- +setstate Kia_eNiro 2024-01-20 20:12:20 ui_command_before_1 --- +setstate Kia_eNiro 2024-01-20 09:38:30 ui_command_before_2 --- +setstate Kia_eNiro 2024-01-19 16:29:40 ui_command_before_3 --- +setstate Kia_eNiro 2024-01-19 19:55:43 ui_command_before_4 --- +setstate Kia_eNiro 2024-01-17 12:15:42 ui_timer_Start 12:50 +setstate Kia_eNiro 2024-01-17 17:49:46 ui_timer_mode Aus \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/WB_0_DbLog_manuelle_Einträge.txt b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/WB_0_DbLog_manuelle_Einträge.txt new file mode 100644 index 000000000..9cb616b6c --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/WB_0_DbLog_manuelle_Einträge.txt @@ -0,0 +1,413 @@ +defmod WB_0 DOIF ################################################################################################################\ +## 1_add fügt einen neuen Eintrag in die Datenbank ein\ +##\ +1_add\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ([$SELF:ui_command_1] eq "add" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ + my $logdbrep = "LogDBRep_WB_0_SQL";;\ + my $BEV = ::ReadingsVal("$SELF","BEV","---");;\ + my $TIMESTAMP = ::ReadingsVal("$SELF","BEV_DateTime","0000-00-00 00:00").":00";;\ + $TIMESTAMP =~ s/_/ /;;\ + my $year = substr($TIMESTAMP,0,4);;\ + my $month = substr($TIMESTAMP,5,2);;\ +# print("$year.$month \n");;\ + my $TYPE = ::ReadingsVal("$SELF","BEV_TYPE","none");;\ + my $READING = $BEV."_kWhActualCharged";;\ + my $VALUE = ::ReadingsVal("$SELF","BEV_kWhActualCharged","0");;\ + my $ret = 0;;\ +\ + if ($TYPE eq "kostenfrei") {\ + set_Reading("BEV_kWhActualCost","0") ;;\ + }\ +\ + if( $BEV ne "---"\ + and $TIMESTAMP ne "00-00-00 00:00:00"\ + and ($VALUE ne "0" or $TYPE eq "kostenfrei")\ + ) {\ +\ + ## Eintragen der Ladeleistung\ +# print("1 $TIMESTAMP $SELF $TYPE $READING $VALUE \n");;\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$TIMESTAMP."','$SELF','".$TYPE."','".$READING."','".$VALUE."')\ + ON DUPLICATE KEY UPDATE\ + TYPE='".$TYPE."',\ + VALUE='".$VALUE."';;") ;;\ +\ + if (AttrVal("$SELF","verbose",0) >=3 and $ret > 1) {\ + Log 3, "$SELF 1_1 : ".$ret;;\ + }\ +\ + ## Eintragen der Ladekosten\ + $READING = $BEV."_kWhActualCost";;\ + $VALUE = ::ReadingsVal("$SELF","BEV_kWhActualCost","0");;\ +# print("2 $TIMESTAMP $SELF $TYPE $READING $VALUE \n");;\ +\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$TIMESTAMP."','$SELF','".$TYPE."','".$READING."','".$VALUE."')\ + ON DUPLICATE KEY UPDATE\ + TYPE='".$TYPE."',\ + VALUE='".$VALUE."';;") ;;\ +\ + if (AttrVal("$SELF","verbose",0) >=3 and $ret > 1) {\ + Log 3, "$SELF 1_2 : ".$ret;;\ + }\ +\ + ## Berechnung des Monats Wertes\ + $READING = $BEV."_kWhCounter_Month";;\ +# print("3 $TIMESTAMP $SELF $TYPE $READING $VALUE \n");;\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + SELECT TIMESTAMP,DEVICE,TYPE,READING,VALUE\ + FROM\ + (SELECT\ + concat(last_day('".$TIMESTAMP."'), ' 23:59:00') AS TIMESTAMP,\ + DEVICE,\ + 'manuell' AS TYPE,\ + '".$READING."' AS READING,\ + sum(VALUE) AS VALUE\ + FROM history\ + WHERE DEVICE='$SELF'\ + AND READING = '".$BEV."_kWhActualCharged'\ + AND YEAR(TIMESTAMP) = YEAR('".$TIMESTAMP."')\ + AND MONTH(TIMESTAMP) = MONTH('".$TIMESTAMP."')\ + ) t1\ + ON DUPLICATE KEY UPDATE\ + VALUE = t1.VALUE ;;") ;;\ +\ + if (AttrVal("$SELF","verbose",0) >=3 and $ret > 2) {\ + Log 3, "$SELF 1_3 : ".$ret;;\ + }\ +\ + ## Setzen des Monats Wertes als reading\ +# print("4 $TIMESTAMP $SELF $TYPE $READING $VALUE \n");;\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + SELECT VALUE FROM history\ + WHERE DEVICE='$SELF'\ + AND READING='".$READING."'\ + AND YEAR(TIMESTAMP) = YEAR(curdate())\ + AND MONTH(TIMESTAMP) = MONTH(curdate()) ;;") ;;\ + set_Reading($READING,$ret) ;;\ +\ + ## Berechnung des Jahres Wertes\ + $READING = $BEV."_kWhCounter_Year";;\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + SELECT TIMESTAMP,DEVICE,TYPE,READING,VALUE\ + FROM\ + (SELECT\ + concat(last_day('".$TIMESTAMP."'), ' 23:59:00') AS TIMESTAMP,\ + DEVICE,\ + 'manuell' AS TYPE,\ + '".$READING."' AS READING,\ + sum(VALUE) AS VALUE\ + FROM history\ + WHERE DEVICE='$SELF'\ + AND READING = '".$BEV."_kWhActualCharged'\ + AND YEAR(TIMESTAMP) = YEAR('".$TIMESTAMP."')\ + AND MONTH(TIMESTAMP) <= MONTH('".$TIMESTAMP."')\ + ) t1\ + ON DUPLICATE KEY UPDATE\ + VALUE = t1.VALUE ;;") ;;\ +\ + if (AttrVal("$SELF","verbose",0) >=3 and $ret > 2) {\ + Log 3, "$SELF 1_4 : ".$ret;;\ + }\ +\ + ## Setzen des Jahres Wertes als reading\ +# print("5 $TIMESTAMP $SELF $TYPE $READING $VALUE \n");;\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + SELECT VALUE FROM history\ + WHERE DEVICE='$SELF'\ + AND READING='".$READING."'\ + AND MONTH(TIMESTAMP) <= MONTH(curdate())\ + ORDER BY TIMESTAMP DESC\ + LIMIT 1 ;;") ;;\ + set_Reading($READING,$ret) ;;\ +\ + ## Anzeigen der bisherigen Einträge\ + my $report = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + SELECT TIMESTAMP,DEVICE,TYPE,READING,VALUE FROM history\ + WHERE DEVICE = '$SELF'\ + AND TYPE != 'manuell'\ + AND TIMESTAMP>DATE_ADD('".$TIMESTAMP."',INTERVAL -1 MONTH)\ + AND TIMESTAMP/g;;\ + $report =~ s/\|/ \| /g;;\ + set_Reading("BEV_last",$report);;\ + }\ +\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 1_5 : add line ".$TIMESTAMP." $SELF Kia_eNiro_kWhCounter*";;\ + }\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +2_delete\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ([$SELF:ui_command_1] eq "delete" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ + my $logdbrep = "LogDBRep_WB_0_SQL";;\ + my $BEV = ::ReadingsVal("$SELF","BEV","---");;\ + my $TIMESTAMP = ::ReadingsVal("$SELF","BEV_DateTime","0000-00-00 00:00").":00";;\ + $TIMESTAMP =~ s/_/ /;;\ + my $TYPE = ::ReadingsVal("$SELF","BEV_TYPE","none");;\ + my $READING = $BEV."_kWhActual%";;\ + my $ret = 0;;\ + if( $BEV ne "---"\ + and $TYPE ne "none"\ + and $TIMESTAMP ne "00-00-00 00:00:00"\ + ) {\ +\ + ## Löschen der Ladeleistung\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + DELETE FROM history\ + WHERE TIMESTAMP = '".$TIMESTAMP."'\ + AND DEVICE = '$SELF'\ + AND TYPE = '".$TYPE."'\ + AND READING LIKE '".$READING."';;") ;;\ +\ + if (AttrVal("$SELF","verbose",0) >=3 and $ret > 2) {\ + Log 3, "$SELF 2_1 : ".$ret;;\ + }\ +\ + ## Berechnung des Monats Wertes\ + $READING = $BEV."_kWhCounter_Month";;\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + SELECT TIMESTAMP,DEVICE,TYPE,READING,VALUE\ + FROM\ + (SELECT\ + concat(last_day('".$TIMESTAMP."'), ' 23:59:00') AS TIMESTAMP,\ + '$SELF' AS DEVICE,\ + 'manuell' AS TYPE,\ + '".$READING."' AS READING,\ + sum(VALUE) AS VALUE\ + FROM\ + (SELECT VALUE\ + FROM history\ + WHERE DEVICE='$SELF'\ + AND READING = '".$BEV."_kWhActualCharged'\ + AND YEAR(TIMESTAMP) = YEAR('".$TIMESTAMP."')\ + AND MONTH(TIMESTAMP) = MONTH('".$TIMESTAMP."')\ + UNION\ + SELECT 0 AS VALUE\ + ) t1\ + ) t2\ + ON DUPLICATE KEY UPDATE\ + VALUE = t2.VALUE ;;") ;;\ +\ + if (AttrVal("$SELF","verbose",0) >=3 and $ret > 2) {\ + Log 3, "$SELF 2_2 : ".$ret;;\ + }\ +\ + ## Setzen des Monats Wertes als reading\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + SELECT VALUE FROM history\ + WHERE DEVICE='$SELF'\ + AND READING='".$READING."'\ + AND MONTH(TIMESTAMP) = MONTH('".$TIMESTAMP."') ;;") ;;\ + set_Reading($READING,$ret) ;;\ +\ + ## Berechnung des Jahres Wertes\ + $READING = $BEV."_kWhCounter_Year";;\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + SELECT TIMESTAMP,DEVICE,TYPE,READING,VALUE\ + FROM\ + (SELECT\ + concat(last_day('".$TIMESTAMP."'), ' 23:59:00') AS TIMESTAMP,\ + DEVICE,\ + 'manuell' AS TYPE,\ + '".$READING."' AS READING,\ + sum(VALUE) AS VALUE\ + FROM history\ + WHERE DEVICE='$SELF'\ + AND READING = '".$BEV."_kWhActualCharged'\ + AND YEAR(TIMESTAMP) = YEAR('".$TIMESTAMP."')\ + AND MONTH(TIMESTAMP) <= MONTH('".$TIMESTAMP."')\ + ) t1\ + ON DUPLICATE KEY UPDATE\ + VALUE = t1.VALUE ;;") ;;\ +\ + if (AttrVal("$SELF","verbose",0) >=3 and $ret > 2) {\ + Log 3, "$SELF 2_3 : ".$ret;;\ + }\ +\ + ## Setzen des Jahres Wertes als reading\ + $ret = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + SELECT VALUE FROM history\ + WHERE DEVICE='$SELF'\ + AND READING='".$READING."'\ + AND MONTH(TIMESTAMP) <= MONTH(curdate())\ + ORDER BY TIMESTAMP DESC\ + LIMIT 1 ;;") ;;\ + set_Reading($READING,$ret) ;;\ +\ + ## Anzeigen der bisherigen Einträge\ + my $report = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + SELECT TIMESTAMP,DEVICE,TYPE,READING,VALUE FROM history\ + WHERE DEVICE = '$SELF'\ + AND TYPE != 'manuell'\ + AND TIMESTAMP>DATE_ADD('".$TIMESTAMP."',INTERVAL -1 MONTH)\ + AND TIMESTAMP/g;;\ + $report =~ s/\|/ \| /g;;\ + set_Reading("BEV_last",$report);;\ + } else {\ + set_Reading("BEV_last","---");;\ + }\ +\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 2_5 : delete line ".$TIMESTAMP." $SELF ".$BEV."_kWhActualCharged";;\ + }\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 3_report erzeugt eine Liste von 30 Einträgen vor dem angegebenen Datum\ +##\ +3_report\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ([$SELF:ui_command_1] eq "report" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ + my $logdbrep = "LogDBRep_WB_0_SQL";;\ + my $BEV = ::ReadingsVal("$SELF","BEV","---");;\ + my $TIMESTAMP = ::ReadingsVal("$SELF","BEV_DateTime","0000-00-00 00:00").":00";;\ + $TIMESTAMP =~ s/_/ /;;\ + my $ret = 0;;\ + if( $BEV ne "---"\ + and $TIMESTAMP ne "00-00-00 00:00:00"\ + ) {\ +\ + my $report = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + SELECT TIMESTAMP,DEVICE,TYPE,READING,VALUE FROM history\ + WHERE DEVICE = '$SELF'\ + AND TIMESTAMP < LAST_DAY('".$TIMESTAMP."') + INTERVAL 1 DAY\ + ORDER BY TIMESTAMP DESC, READING\ + LIMIT 24;;") ;;\ + if ($report ne "1") {\ + $report =~ s/\n/
/g;;\ +## $report =~ s/\|/ ;/g;;\ +## $report = "
".$report."
";;\ + $report =~ s/\|/ \| /g;;\ + set_Reading("BEV_last",$report);;\ + }\ +\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 3_report erzeugt eine Liste von 30 Einträgen vor dem angegebenen Datum\ +##\ +3_report_clear\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ([$SELF:ui_command_1] eq "report_clear" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + set_Reading("BEV_last","Kein Report abgerufen");;\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +} +attr WB_0 DbLogExclude .* +attr WB_0 disable 0 +attr WB_0 group PV Eigenverbrauch-Steuerung +attr WB_0 icon car +attr WB_0 room Strom->Photovoltaik +attr WB_0 sortby 404 +attr WB_0 uiTable {\ +package ui_Table;;\ +## $TR{0} = "style='color:yellow;;text-align:left;;font-weight:bold;;font-size:18px'";; ## Reihe 0 für Überschrift\ + $TABLE = "style='width:100%;;'";;\ +\ + $TD{0..3}{0} = "align='center' style='font-size:16px;;border-right-style:solid;;border-color:darkgreen;;border-right-width:2px;;width:26%'";;\ +\ + $TD{0..3}{1} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ + $TD{0..3}{2..4} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ + $TD{0..3}{5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ +\ + $TD{4}{0} = "align='center' style='font-size:16px;;border-right-style:solid;;border-color:darkgreen;;border-right-width:2px;;width:26%'";;\ + $TD{4}{1} = "style='border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-bottom-width:2px;;border-right-width:1px;;width:69%;;font-weight:bold;;'";;\ +\ +}\ +\ +"$SELF"|"" |""|""|""|""\ +\ +"" |\ +widget([$SELF:BEV_DateTime],"datetime,step:15,inline:true,format:Y-m-d_H:i") |\ +widget([$SELF:BEV],"uzsuDropDown,---,Kia_eNiro,Gast")."
".widget([$SELF:BEV_TYPE],"uzsuDropDown,---,Karte_1,privat,kostenfrei") | widget([$SELF:BEV_kWhActualCharged],"selectnumbers,0,1,100,0,lin")."kWh" |\ +widget([$SELF:BEV_kWhActualCost],"selectnumbers,0,0.1,100,2,lin")."Eur" |\ +widget([$SELF:ui_command_1],"uzsuDropDown,---,add,delete,report,report_clear")\ +\ +"" |\ +[$SELF:BEV_DateTime].":00" |\ +[$SELF:BEV] |\ +[$SELF:BEV_kWhActualCharged]." kWh" |\ +[$SELF:BEV_kWhActualCost]." Eur" |\ +[$SELF:BEV_TYPE]\ +\ +|"Statistik Ladeleistung
lp_1
lp_2
"|\ +"
Kia_eNiro
Gast"|\ +|\ +"Monat/Vormonat
".sprintf("%03d / %03d",::ReadingsVal("$SELF","Kia_eNiro_kWhCounter_Month",0),::ReadingsVal("LogDBRep_Statistic_previous_Month","$SELF_Kia_eNiro_kWhCounter_Month",0))."
".sprintf("%03d / %03d",::ReadingsVal("$SELF","Gast_kWhCounter_Month",0),::ReadingsVal("LogDBRep_Statistic_previous_Month","$SELF_Gast_kWhCounter_Month",0))|\ +"Jahr/Vorjahr
".sprintf("%04d / %04d",::ReadingsVal("$SELF","Kia_eNiro_kWhCounter_Year",0),::ReadingsVal("LogDBRep_Statistic_previous_Year","$SELF_Kia_eNiro_kWhCounter_Year",0))."
".sprintf("%04d / %04d",::ReadingsVal("$SELF","Gast_kWhCounter_Year",0),::ReadingsVal("LogDBRep_Statistic_previous_Year","$SELF_Gast_kWhCounter_Year",0))<\ +\ +""|\ +[$SELF:BEV_last] +attr WB_0 userReadings BEV_last:BEV_DateTime|BEV_TYPE|BEV.* {\ + my $logdbrep = "LogDBRep_WB_0_SQL";;\ + my $BEV = ::ReadingsVal("$NAME","BEV","---");;\ + my $TYPE = ::ReadingsVal("$NAME","BEV_TYPE","---");;\ + my $TIMESTAMP = ::ReadingsVal("$NAME","BEV_DateTime","0000-00-00 00:00").":00";;\ + $TIMESTAMP =~ s/_/ /;;\ + my $report = ::CommandGet(undef, $logdbrep." sqlCmdBlocking\ + SELECT TIMESTAMP,DEVICE,TYPE,READING,VALUE FROM history\ + WHERE DEVICE = '$NAME'\ + AND TYPE = '".$TYPE."'\ + AND READING LIKE '".$BEV."%'\ + AND TIMESTAMP='".$TIMESTAMP."';;") ;;\ + if ($report ne "") {\ + $report =~ s/\n/
/g;;\ + $report =~ s/\|/ \| /g;;\ + } else {\ + $report = "---";;\ + };;\ + $report;;\ +} +attr WB_0 verbose 3 + +setstate WB_0 2023-01-20 19:25:31 BEV Kia_eNiro +setstate WB_0 2024-01-12 17:40:57 BEV_DateTime 2024-01-12_19:00 +setstate WB_0 2023-12-15 19:33:25 BEV_TYPE privat +setstate WB_0 2023-12-31 09:59:36 BEV_kWhActualCharged 40 +setstate WB_0 2023-12-31 10:00:53 BEV_kWhActualCost 27.70 +setstate WB_0 2024-01-12 17:40:57 BEV_last --- +setstate WB_0 2024-01-01 11:39:15 ui_command_1 --- diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/WB_1_openWB.txt b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/WB_1_openWB.txt new file mode 100644 index 000000000..ecfba526a --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wallbox_openWB_mit_Kia_eNiro/WB_1_openWB.txt @@ -0,0 +1,263 @@ +defmod WB_1 MQTT2_DEVICE WB_1_MQTT2 +attr WB_1 DbLogExclude .* +attr WB_1 DbLogInclude lp_.*_.*,.*AllChargePoints.*,ChargeMode +attr WB_1 IODev WB_1_MQTT2 +attr WB_1 alias WB_1 +attr WB_1 autocreate 0 +attr WB_1 comment Die openWB besteht aus zwei Ladepunkten. +attr WB_1 devicetopic openWB +attr WB_1 disable 0 +attr WB_1 event-on-change-reading lp_.*_.*,.*AllChargePoints.*,ChargeMode,bool70.* +attr WB_1 event-on-update-reading lp_2_kWhChargedSincePlugged_RFID +attr WB_1 group PV Eigenverbrauch-Steuerung +attr WB_1 icon fuel +attr WB_1 readingList $DEVICETOPIC/global/WHouseConsumption:.* WHouseConsumption\ +$DEVICETOPIC/global/WAllChargePoints:.* WAllChargePoints\ +$DEVICETOPIC/global/ChargeMode:.* {my %h=(0=>'SofortLaden',1=>'MinPV',2=>'NurPV',3=>'Stop',4=>'Standby');; return {ChargeMode=>$h{$EVENT}}}\ +\ +$DEVICETOPIC/global/awattar/boolAwattarEnabled:.* boolAwattarEnabled\ +$DEVICETOPIC/global/awattar/ActualPriceForCharging:.* ActualPriceForCharging\ +$DEVICETOPIC/global/awattar/MaxPriceForCharging:.* MaxPriceForCharging\ +$DEVICETOPIC/global/boolRse:.* boolRse\ +$DEVICETOPIC/global/DailyYieldAllChargePointsKwh:.* DailyYieldAllChargePointsKwh\ +$DEVICETOPIC/global/rfidConfigured:.* rfidConfigured\ +$DEVICETOPIC/global/kWhCounterAllChargePoints:.* kWhCounterAllChargePoints\ +$DEVICETOPIC/global/strLastmanagementActive:.* strLastmanagementActive\ +$DEVICETOPIC/global/ETProvider/modulePath:.* modulePath\ +$DEVICETOPIC/global/cpuTemp:.* cpuTemp\ +\ +$DEVICETOPIC/system/Uptime:.* Uptime\ +$DEVICETOPIC/system/Date:.* Date\ +$DEVICETOPIC/system/Timestamp:.* Timestamp\ +$DEVICETOPIC/system/Version:.* Version\ +$DEVICETOPIC/system/IpAddress:.* IpAddress\ +$DEVICETOPIC/system/lastRfId:.* lastRfId\ +$DEVICETOPIC/system/updateInProgress:.* updateInProgress\ +$DEVICETOPIC/system/ConfiguredChargePoints:.* ConfiguredChargePoints\ +$DEVICETOPIC/system/lastlivevalues:.* lastlivevalues\ +$DEVICETOPIC/system/randomSleep:.* randomSleep\ +$DEVICETOPIC/system/wizzardDone:.* wizzardDone\ +$DEVICETOPIC/system/priceForKWh:.* priceForKWh\ +$DEVICETOPIC/system/reloadDisplay:.* reloadDisplay\ +\ +$DEVICETOPIC/evu/ASchieflast:.* ASchieflast\ +\ +$DEVICETOPIC/lp/1/P%Soc:.* lp_1_Pct_Soc\ +$DEVICETOPIC/lp/1/%Soc:.* lp_1_current_Soc\ +$DEVICETOPIC/lp/1/\x25Soc:.* lp_1__Soc\ +\ +$DEVICETOPIC/lp/1/countPhasesInUse:.* lp_1_countPhasesInUse\ +$DEVICETOPIC/lp/1/ChargePointEnabled:.* lp_1_ChargePointEnabled\ +$DEVICETOPIC/lp/1/ChargeStatus:.* lp_1_ChargeStatus\ +\ +$DEVICETOPIC/lp/1/kWhDailyCharged:.* lp_1_kWhDailyCharged\ +$DEVICETOPIC/lp/1/kWhCounter:.* lp_1_kWhCounter\ +$DEVICETOPIC/lp/1/kWhActualCharged:.* lp_1_kWhActualCharged\ +$DEVICETOPIC/lp/1/kWhChargedSincePlugged:.* lp_1_kWhChargedSincePlugged\ +$DEVICETOPIC/lp/1/energyConsumptionPer100km:.* lp_1_energyConsumptionPer100km\ +$DEVICETOPIC/lp/1/kmCharged:.* lp_1_kmCharged\ +\ +$DEVICETOPIC/lp/1/strChargePointName:.* lp_1_strChargePointName\ +$DEVICETOPIC/lp/1/TimeRemaining:.* lp_1_TimeRemaining\ +\ +$DEVICETOPIC/lp/1/PfPhase2:.* lp_1_PfPhase2\ +$DEVICETOPIC/lp/1/PfPhase3:.* lp_1_PfPhase3\ +$DEVICETOPIC/lp/1/PfPhase1:.* lp_1_PfPhase1\ +$DEVICETOPIC/lp/1/W:.* lp_1_W\ +\ +$DEVICETOPIC/lp/1/boolPlugStat:.* {my %h=(0=>'no Plug',1=>'Plugged in');; return {lp_1_PlugStat=>$h{$EVENT}}}\ +$DEVICETOPIC/lp/1/boolChargeStat:.* {my %h=(0=>'not loading',1=>'loading');; return {lp_1_ChargeStat=>$h{$EVENT}}}\ +$DEVICETOPIC/lp/1/AConfigured:.* lp_1_AConfigured\ +\ +$DEVICETOPIC/lp/1/boolChargePointConfigured:.* lp_1_boolChargePointConfigured\ +$DEVICETOPIC/lp/1/boolSocConfigured:.* lp_1_boolSocConfigured\ +$DEVICETOPIC/lp/1/boolDirectModeChargekWh:.* lp_1_boolDirectModeChargekWh\ +$DEVICETOPIC/lp/1/boolDirectChargeModeSoc:.* lp_1_boolDirectChargeModeSoc\ +$DEVICETOPIC/lp/1/boolFinishAtTimeChargeActive:.* lp_1_boolFinishAtTimeChargeActive\ +$DEVICETOPIC/lp/1/boolChargeAtNight:.* lp_1_boolChargeAtNight\ +$DEVICETOPIC/lp/1/boolSocManual:.* lp_1_boolSocManual\ +\ +$DEVICETOPIC/lp/1/AutolockStatus:.* lp_1_AutolockStatus\ +$DEVICETOPIC/lp/1/AutolockConfigured:.* lp_1_AutolockConfigured\ +\ +$DEVICETOPIC/lp/1/lastRfId:.* lp_1_lastRfId\ +$DEVICETOPIC/lp/1/pluggedladungakt:.* lp_1_pluggedladungakt\ +$DEVICETOPIC/lp/1/plugStartkWh:.* lp_1_plugStartkWh\ +$DEVICETOPIC/lp/1/MeterSerialNumber:.* lp_1_MeterSerialNumber\ +\ +\ +$DEVICETOPIC/lp/2/P%Soc:.* lp_2_Pct_Soc\ +$DEVICETOPIC/lp/2/%Soc:.* lp_2_current_Soc\ +$DEVICETOPIC/lp/2/\x25Soc:.* lp_2__Soc\ +\ +$DEVICETOPIC/lp/2/countPhasesInUse:.* lp_2_countPhasesInUse\ +$DEVICETOPIC/lp/2/ChargePointEnabled:.* lp_2_ChargePointEnabled\ +$DEVICETOPIC/lp/2/ChargeStatus:.* lp_2_ChargeStatus\ +\ +$DEVICETOPIC/lp/2/kWhDailyCharged:.* lp_2_kWhDailyCharged\ +$DEVICETOPIC/lp/2/kWhCounter:.* lp_2_kWhCounter\ +$DEVICETOPIC/lp/2/kWhActualCharged:.* lp_2_kWhActualCharged\ +$DEVICETOPIC/lp/2/kWhChargedSincePlugged:.* lp_2_kWhChargedSincePlugged\ +$DEVICETOPIC/lp/2/energyConsumptionPer100km:.* lp_2_energyConsumptionPer100km\ +$DEVICETOPIC/lp/2/kmCharged:.* lp_2_kmCharged\ +\ +$DEVICETOPIC/lp/2/strChargePointName:.* lp_2_strChargePointName\ +$DEVICETOPIC/lp/2/TimeRemaining:.* lp_2_TimeRemaining\ +\ +$DEVICETOPIC/lp/2/W:.* lp_2_W\ +\ +$DEVICETOPIC/lp/2/boolPlugStat:.* {my %h=(0=>'no Plug',1=>'Plugged in');; return {lp_2_PlugStat=>$h{$EVENT}}}\ +$DEVICETOPIC/lp/2/boolChargeStat:.* {my %h=(0=>'not loading',1=>'loading');; return {lp_2_ChargeStat=>$h{$EVENT}}}\ +$DEVICETOPIC/lp/2/AConfigured:.* lp_2_AConfigured\ +\ +$DEVICETOPIC/lp/2/boolChargePointConfigured:.* lp_2_boolChargePointConfigured\ +$DEVICETOPIC/lp/2/boolSocConfigured:.* lp_2_boolSocConfigured\ +$DEVICETOPIC/lp/2/boolDirectModeChargekWh:.* lp_2_boolDirectModeChargekWh\ +$DEVICETOPIC/lp/2/boolDirectChargeModeSoc:.* lp_2_boolDirectChargeModeSoc\ +$DEVICETOPIC/lp/2/boolFinishAtTimeChargeActive:.* lp_2_boolFinishAtTimeChargeActive\ +$DEVICETOPIC/lp/2/boolChargeAtNight:.* lp_2_boolChargeAtNight\ +$DEVICETOPIC/lp/2/boolSocManual:.* lp_2_boolSocManual\ +\ +$DEVICETOPIC/lp/2/AutolockStatus:.* lp_2_AutolockStatus\ +$DEVICETOPIC/lp/2/AutolockConfigured:.* lp_2_AutolockConfigured\ +\ +$DEVICETOPIC/lp/2/lastRfId:.* lp_2_lastRfId\ +$DEVICETOPIC/lp/2/pluggedladungakt:.* lp_2_pluggedladungakt\ +$DEVICETOPIC/lp/2/plugStartkWh:.* lp_2_plugStartkWh\ +$DEVICETOPIC/lp/2/MeterSerialNumber:.* lp_2_MeterSerialNumber\ +\ +\ +$DEVICETOPIC/boolChargeAtNight_direct:.* boolChargeAtNight_direct\ +$DEVICETOPIC/boolChargeAtNight_nurpv:.* boolChargeAtNight_nurpv\ +$DEVICETOPIC/boolChargeAtNight_minpv:.* boolChargeAtNight_minpv\ +$DEVICETOPIC/boolDisplayHouseConsumption:.* boolDisplayHouseConsumption\ +$DEVICETOPIC/boolDisplayDailyCharged:.* boolDisplayDailyCharged\ +$DEVICETOPIC/boolEvuSmoothedActive:.* boolEvuSmoothedActive\ +$DEVICETOPIC/pv/bool70PVDynActive:.* bool70PVDynActive\ +$DEVICETOPIC/pv/W70PVDyn:.* W70PVDyn\ +$DEVICETOPIC/pv/bool70PVDynStatus:.* bool70PVDynStatus\ +$DEVICETOPIC/pv/CounterTillStartPvCharging:.* CounterTillStartPvCharging\ +$DEVICETOPIC/pv/W:.* W\ +$DEVICETOPIC/config/get/pv/nurpv70dynact:.* nurpv70dynact\ +$DEVICETOPIC/config/get/pv/nurpv70dynw:.* nurpv70dynw\ +\ +$DEVICETOPIC/config/get/pv/priorityModeEVBattery:.* priorityModeEVBattery\ +$DEVICETOPIC/config/get/pv/lp/1/minSocAlwaysToChargeTo:.* lp_1_minSocAlwaysToChargeTo\ +$DEVICETOPIC/config/get/pv/lp/1/maxSoc:.* lp_1_maxSoc\ +$DEVICETOPIC/config/get/pv/lp/1/minSocAlwaysToChargeToCurrent:.* lp_1_minSocAlwaysToChargeToCurrent\ +$DEVICETOPIC/config/get/pv/lp/1/maxSocToChargeTo:.* lp_1_maxSocToChargeTo\ +$DEVICETOPIC/config/get/pv/lp/1/minCurrent:.* lp_1_minCurrent\ +$DEVICETOPIC/config/get/pv/lp/1/socLimitation:.* lp_1_socLimitation\ +$DEVICETOPIC/config/get/pv/lp/2/minCurrent:.* lp_2_minCurrent\ +$DEVICETOPIC/config/get/pv/lp/2/maxSoc:.* lp_2_maxSoc\ +$DEVICETOPIC/config/get/pv/lp/2/socLimitation:.* lp_2_socLimitation\ +$DEVICETOPIC/config/get/pv/socStopChargeAtMinPv:.* socStopChargeAtMinPv\ +$DEVICETOPIC/config/get/pv/regulationPoint:.* regulationPoint\ +$DEVICETOPIC/config/get/pv/minBatteryDischargeSocAtBattPriority:.* minBatteryDischargeSocAtBattPriority\ +$DEVICETOPIC/config/get/pv/minBatteryChargePowerAtEvPriority:.* minBatteryChargePowerAtEvPriority\ +$DEVICETOPIC/config/get/pv/minFeedinPowerBeforeStart:.* minFeedinPowerBeforeStart\ +$DEVICETOPIC/config/get/pv/boolAdaptiveCharging:.* boolAdaptiveCharging\ +$DEVICETOPIC/config/get/pv/adaptiveChargingFactor:.* adaptiveChargingFactor\ +$DEVICETOPIC/config/get/pv/batteryDischargePowerAtBattPriority:.* batteryDischargePowerAtBattPriority\ +$DEVICETOPIC/config/get/pv/boolShowPriorityIconInTheme:.* boolShowPriorityIconInTheme\ +$DEVICETOPIC/config/get/pv/maxPowerConsumptionBeforeStop:.* maxPowerConsumptionBeforeStop\ +$DEVICETOPIC/config/get/pv/stopDelay:.* stopDelay\ +$DEVICETOPIC/config/get/pv/chargeSubmode:.* chargeSubmode\ +$DEVICETOPIC/config/get/pv/minCurrentMinPv:.* minCurrentMinPv\ +$DEVICETOPIC/config/get/pv/socStartChargeAtMinPv:.* socStartChargeAtMinPv\ +$DEVICETOPIC/config/get/pv/startDelay:.* startDelay\ +$DEVICETOPIC/config/get/sofort/lp/2/energyToCharge:.* lp_2_energyToCharge\ +$DEVICETOPIC/config/get/sofort/lp/2/chargeLimitation:.* lp_2_chargeLimitation\ +$DEVICETOPIC/config/get/sofort/lp/2/socToChargeTo:.* lp_2_socToChargeTo\ +$DEVICETOPIC/config/get/sofort/lp/2/current:.* lp_2_current\ +\ +$DEVICETOPIC/config/get/sofort/lp/1/socToChargeTo:.* lp_1_socToChargeTo\ +\ +$DEVICETOPIC/config/get/sofort/lp/1/energyToCharge:.* lp_1_energyToCharge\ +$DEVICETOPIC/config/get/sofort/lp/1/chargeLimitation:.* lp_1_chargeLimitation\ +$DEVICETOPIC/config/get/sofort/lp/1/current:.* lp_1_current\ +$DEVICETOPIC/config/get/global/minEVSECurrentAllowed:.* minEVSECurrentAllowed\ +$DEVICETOPIC/config/get/global/maxEVSECurrentAllowed:.* maxEVSECurrentAllowed\ +$DEVICETOPIC/config/get/global/dataProtectionAcknoledged:.* dataProtectionAcknoledged\ +$DEVICETOPIC/config/get/global/slaveMode:.* slaveMode\ +$DEVICETOPIC/config/get/u1p3p/standbyPhases:.* standbyPhases\ +$DEVICETOPIC/config/get/u1p3p/sofortPhases:.* sofortPhases\ +$DEVICETOPIC/config/get/u1p3p/nachtPhases:.* nachtPhases\ +$DEVICETOPIC/config/get/u1p3p/minundpvPhases:.* minundpvPhases\ +$DEVICETOPIC/config/get/u1p3p/nurpvPhases:.* nurpvPhases\ +$DEVICETOPIC/config/get/u1p3p/isConfigured:.* isConfigured\ +$DEVICETOPIC/boolChargeAtNight_standby:.* boolChargeAtNight_standby\ +$DEVICETOPIC/set/system/reloadDisplay:.* reloadDisplay\ +$DEVICETOPIC/set/system/topicSender:.* topicSender\ +$DEVICETOPIC/set/lp/2/ChargePointEnabled:.* lp_2_ChargePointEnabled\ +\ + +attr WB_1 room 2_PV_Steuerung,MQTT2_DEVICE,Strom->Photovoltaik +attr WB_1 setList Lademodus:SofortLaden,MinPV,NurPV,Stop,Standby { my %h=(SofortLaden=>'0','MinPV'=>'1',NurPV=>'2',Stop=>'3',Standby=>'4');;qq($DEVICETOPIC/set/ChargeMode $h{$EVTPART1}) }\ +DirectChargeSubMode:Aus,kWh_Laden,SoC_Laden { my %h=(Aus=>'0',kWh_Laden=>'1',SoC_Laden=>'2');;qq($DEVICETOPIC/set/lp1/DirectChargeSubMode $h{$EVTPART1}) }\ +lp_1_socToChargeTo:50,60,70,80,90,100 { qq($DEVICETOPIC/config/set/sofort/lp/1/socToChargeTo $EVTPART1) }\ +priorityModeEVBattery:0,1 { qq($DEVICETOPIC/config/set/pv/priorityModeEVBattery $EVTPART1) }\ +\ +nurpv70dynact:0,1 { qq($DEVICETOPIC/config/set/pv/nurpv70dynact $EVTPART1) }\ +nurpv70dynw { qq($DEVICETOPIC/config/set/pv/nurpv70dynw $EVTPART1) }\ +\ +NurPV70Status:0,1 { qq($DEVICETOPIC/set/pv/NurPV70Status $EVTPART1) }\ +\ +lp_1_current:10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 { qq($DEVICETOPIC/config/set/sofort/lp/1/current $EVTPART1) }\ +lp_2_current:10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 { qq($DEVICETOPIC/config/set/sofort/lp/2/current $EVTPART1) } +attr WB_1 sortby 403 +attr WB_1 stateFormat {\ + my $MonthBefore='LogDBRep_Statistic_previous_Month';;\ + my $YearBefore='LogDBRep_Statistic_previous_Year';;\ + my $DUMMY = "";;\ + my $date = POSIX::strftime("%Y-%m-%d",localtime(time_str2num(ReadingsTimestamp($name, "lastlivevalues",0))));;\ +\ + my $ChargeMode = ReadingsVal($name,"ChargeMode","n/a");;\ + $ChargeMode = ($ChargeMode eq "SofortLaden")? "SofortLaden" : ($ChargeMode eq "MinPV")? "Min+PV" : ($ChargeMode eq "NurPV")? "NurPV" : $ChargeMode;;\ + \ + my $lp_1_Name = ReadingsVal($name,"lp_1_strChargePointName","n/a");;\ + my $lp_1_Power = ReadingsVal($name,"lp_1_W",0)." W";;\ + my $lp_1_Power_1 = ReadingsVal($name,"lp_1_countPhasesInUse",0)."P ".ReadingsVal($name,"lp_1_AConfigured",0)."A";;\ + my $lp_1_Status_1 = ReadingsVal($name,"lp_1_PlugStat","n/a")."
".ReadingsVal($name,"lp_1_ChargeStat","n/a");;\ + my $lp_1_Status_2 = ReadingsVal($name,"lp_1_TimeRemaining","n/a");;\ +\ + my $lp_1_Power_d = sprintf("%5.2f / %5.2f",ReadingsVal($name,"lp_1_kWhDailyCharged",0),ReadingsVal($name,"lp_1_kWhChargedSincePlugged",0));;\ + my $lp_1_Power_m = sprintf("%03d / %03d",ReadingsVal($name,"lp_1_kWhCounter_Month",0),ReadingsVal($MonthBefore,$name."_lp_1_kWhCounter_Month",0));;\ + my $lp_1_Power_j = sprintf("%04d / %04d",ReadingsVal($name,"lp_1_kWhCounter_Year",0),ReadingsVal($YearBefore,$name."_lp_1_kWhCounter_Year",0));;\ + my $lp_1_Power_t = round(ReadingsVal($name,"lp_1_kWhCounter",0),0);;\ +\ + my $lp_2_Name = ReadingsVal($name,"lp_2_strChargePointName","n/a");;\ + my $lp_2_Power = ReadingsVal($name,"lp_2_W",0)." W";;\ + my $lp_2_Power_1 = ReadingsVal($name,"lp_2_countPhasesInUse",0)."P ".ReadingsVal($name,"lp_2_AConfigured",0)."A";;\ + my $lp_2_Status_1 = ReadingsVal($name,"lp_2_PlugStat","n/a")."
".ReadingsVal($name,"lp_2_ChargeStat","n/a");;\ + my $lp_2_Status_2 = "
".ReadingsVal($name,"lp_2_TimeRemaining","n/a");;\ +\ + my $lp_2_Power_d = sprintf("%5.2f / %5.2f",ReadingsVal($name,"lp_2_kWhDailyCharged",0),ReadingsVal($name,"lp_2_kWhChargedSincePlugged",0));;\ + my $lp_2_Power_m = sprintf("%03d / %03d",ReadingsVal($name,"lp_2_kWhCounter_Month",0),ReadingsVal($MonthBefore,$name."_lp_2_kWhCounter_Month",0));;\ + my $lp_2_Power_j = sprintf("%04d / %04d",ReadingsVal($name,"lp_2_kWhCounter_Year",0),ReadingsVal($YearBefore,$name."_lp_2_kWhCounter_Year",0));;\ + my $lp_2_Power_t = round(ReadingsVal($name,"lp_2_kWhCounter",0),0);;\ +\ +"\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
Wallbox$ChargeModeStatusRestladezeitLeistung
 ; ;".$lp_1_Name."".$DUMMY."".$lp_1_Status_1."".$lp_1_Status_2."
".$lp_1_Power_1."
".$lp_1_Power."
 ; ;".$lp_2_Name."".$DUMMY."".$lp_2_Status_1."".$lp_2_Status_2."
".$lp_2_Power_1."
".$lp_2_Power."
Statistik vom $date im kWhaktuellHeute / letztesMonat/VormonatJahr/Vorjahr
 ; ;".$lp_1_Name."".$lp_1_Power."".$lp_1_Power_d."".$lp_1_Power_m."
".$lp_1_Power_j."
 ; ;".$lp_2_Name."".$lp_2_Power."".$lp_2_Power_d."".$lp_2_Power_m."
".$lp_2_Power_j."
\ +"\ +} +attr WB_1 userReadings lp_1_kWhCounter_Month:lp_1_kWhCounter.* { round(ReadingsVal("$NAME","lp_1_kWhCounter",0) - ReadingsVal("$NAME","lp_1_kWhCounter_init_Month",0),0) },\ +lp_1_kWhCounter_Year:lp_1_kWhCounter.* { round(ReadingsVal("$NAME","lp_1_kWhCounter",0) - ReadingsVal("$NAME","lp_1_kWhCounter_init_Year",0),0) },\ +\ +lp_2_kWhCounter_Month:lp_2_kWhCounter.* { round(ReadingsVal("$NAME","lp_2_kWhCounter",0) - ReadingsVal("$NAME","lp_2_kWhCounter_init_Month",0),0) },\ +lp_2_kWhCounter_Year:lp_2_kWhCounter.* { round(ReadingsVal("$NAME","lp_2_kWhCounter",0) - ReadingsVal("$NAME","lp_2_kWhCounter_init_Year",0),0) },\ +\ +lp_2_kWhChargedSincePlugged_RFID:lp_2_PlugStat.* { (ReadingsVal("$NAME","lp_2_PlugStat",'NULL') eq 'Plugged in')?'Wer lädt gerade?':'NULL' } \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_0_KSEM.txt b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_0_KSEM.txt new file mode 100644 index 000000000..d39f64316 --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_0_KSEM.txt @@ -0,0 +1,181 @@ +defmod WR_0_KSEM ModbusAttr 1 60 192.168.178.17:502 TCP +attr WR_0_KSEM DbLogExclude .* +attr WR_0_KSEM DbLogInclude Active_energy.* +attr WR_0_KSEM alias WR_0_KSEM +attr WR_0_KSEM comment Version 2021.04.07 12:00\ +Der KSEM ermittelt nicht alle Werte, welche in der SunSpec spezifiziert sind.\ +Alle nicht unterstützen Werte sind mit 0x8000 gekennzeichnet.\ +Für die nicht unterstützten Zählerstände wird die 0x800000000 ausgegeben.\ +\ +Der Summenstrom M_AC_Current (sum of active phases) kann aber durch den Endanwender selber\ +berechnet werden aus der Summe der Einzelwerte (Phase A AC current, Phase B AC current Phase C AC current)\ +\ +Die einzelnen Spannungen zwischen den Phasen können nicht gemessen werden und werden deshalb nicht ausgegeben. +attr WR_0_KSEM dev-h-defPoll 1 +attr WR_0_KSEM dev-type-INT16-len 1 +attr WR_0_KSEM dev-type-INT16-unpack s> +attr WR_0_KSEM dev-type-INT16_Current-expr $val * (10 ** ReadingsNum("$name" ,"M_AC_Current_SF",0)) +attr WR_0_KSEM dev-type-INT16_Current-format %.2f +attr WR_0_KSEM dev-type-INT16_Current-len 1 +attr WR_0_KSEM dev-type-INT16_Current-unpack s> +attr WR_0_KSEM dev-type-INT16_Freq-expr $val * (10 ** ReadingsNum("$name" ,"M_AC_Freq_SF",0)) +attr WR_0_KSEM dev-type-INT16_Freq-format %.2f +attr WR_0_KSEM dev-type-INT16_Freq-len 1 +attr WR_0_KSEM dev-type-INT16_Freq-unpack s> +attr WR_0_KSEM dev-type-INT16_PF-expr $val * (10 ** ReadingsNum("$name" ,"M_AC_PF_SF",0)) +attr WR_0_KSEM dev-type-INT16_PF-format %.2f +attr WR_0_KSEM dev-type-INT16_PF-len 1 +attr WR_0_KSEM dev-type-INT16_PF-unpack s> +attr WR_0_KSEM dev-type-INT16_Power-expr $val * (10 ** ReadingsNum("$name" ,"M_AC_Power_SF",0)) +attr WR_0_KSEM dev-type-INT16_Power-format %.2f +attr WR_0_KSEM dev-type-INT16_Power-len 1 +attr WR_0_KSEM dev-type-INT16_Power-unpack s> +attr WR_0_KSEM dev-type-INT16_VA-expr $val * (10 ** ReadingsNum("$name" ,"M_AC_VA_SF",0)) +attr WR_0_KSEM dev-type-INT16_VA-format %.2f +attr WR_0_KSEM dev-type-INT16_VA-len 1 +attr WR_0_KSEM dev-type-INT16_VA-unpack s> +attr WR_0_KSEM dev-type-INT16_VAR-expr $val * (10 ** ReadingsNum("$name" ,"M_AC_VAR_SF",0)) +attr WR_0_KSEM dev-type-INT16_VAR-format %.2f +attr WR_0_KSEM dev-type-INT16_VAR-len 1 +attr WR_0_KSEM dev-type-INT16_VAR-unpack s> +attr WR_0_KSEM dev-type-INT16_Voltage-expr $val * (10 ** ReadingsNum("$name" ,"M_AC_Voltage_SF",0)) +attr WR_0_KSEM dev-type-INT16_Voltage-format %.2f +attr WR_0_KSEM dev-type-INT16_Voltage-len 1 +attr WR_0_KSEM dev-type-INT16_Voltage-unpack s> +attr WR_0_KSEM dev-type-STR32-expr $val =~ s/[\00]+//gr +attr WR_0_KSEM dev-type-STR32-format %s +attr WR_0_KSEM dev-type-STR32-len 16 +attr WR_0_KSEM dev-type-STR32-unpack a* +attr WR_0_KSEM dev-type-UINT16-format %s +attr WR_0_KSEM dev-type-UINT16-len 1 +attr WR_0_KSEM dev-type-UINT32-format %s +attr WR_0_KSEM dev-type-UINT32-len 2 +attr WR_0_KSEM dev-type-UINT64-expr $val/10000 +attr WR_0_KSEM dev-type-UINT64-format %s +attr WR_0_KSEM dev-type-UINT64-len 4 +attr WR_0_KSEM dev-type-UINT64-unpack Q> +attr WR_0_KSEM disable 0 +attr WR_0_KSEM event-on-change-reading Active_energy.*,M_AC_Current_.*,M_AC_Power +attr WR_0_KSEM group PV Eigenverbrauch +attr WR_0_KSEM icon measure_power +attr WR_0_KSEM obj-h40072-reading M_AC_Current_A +attr WR_0_KSEM obj-h40072-type INT16_Current +attr WR_0_KSEM obj-h40073-reading M_AC_Current_B +attr WR_0_KSEM obj-h40073-type INT16_Current +attr WR_0_KSEM obj-h40074-reading M_AC_Current_C +attr WR_0_KSEM obj-h40074-type INT16_Current +attr WR_0_KSEM obj-h40075-reading M_AC_Current_SF +attr WR_0_KSEM obj-h40075-type INT16 +attr WR_0_KSEM obj-h40077-reading M_AC_Voltage_AN +attr WR_0_KSEM obj-h40077-type INT16_Voltage +attr WR_0_KSEM obj-h40078-reading M_AC_Voltage_BN +attr WR_0_KSEM obj-h40078-type INT16_Voltage +attr WR_0_KSEM obj-h40079-reading M_AC_Voltage_CN +attr WR_0_KSEM obj-h40079-type INT16_Voltage +attr WR_0_KSEM obj-h40084-reading M_AC_Voltage_SF +attr WR_0_KSEM obj-h40084-type INT16 +attr WR_0_KSEM obj-h40085-reading M_AC_Freq +attr WR_0_KSEM obj-h40085-type INT16_Freq +attr WR_0_KSEM obj-h40086-reading M_AC_Freq_SF +attr WR_0_KSEM obj-h40086-type INT16 +attr WR_0_KSEM obj-h40087-format %.0f +attr WR_0_KSEM obj-h40087-reading M_AC_Power +attr WR_0_KSEM obj-h40087-type INT16_Power +attr WR_0_KSEM obj-h40088-reading M_AC_Power_A +attr WR_0_KSEM obj-h40088-type INT16_Power +attr WR_0_KSEM obj-h40089-reading M_AC_Power_B +attr WR_0_KSEM obj-h40089-type INT16_Power +attr WR_0_KSEM obj-h40090-reading M_AC_Power_C +attr WR_0_KSEM obj-h40090-type INT16_Power +attr WR_0_KSEM obj-h40091-reading M_AC_Power_SF +attr WR_0_KSEM obj-h40091-type INT16 +attr WR_0_KSEM obj-h40092-reading M_AC_VA +attr WR_0_KSEM obj-h40092-type INT16_VA +attr WR_0_KSEM obj-h40093-reading M_AC_VA_A +attr WR_0_KSEM obj-h40093-type INT16_VA +attr WR_0_KSEM obj-h40094-reading M_AC_VA_B +attr WR_0_KSEM obj-h40094-type INT16_VA +attr WR_0_KSEM obj-h40095-reading M_AC_VA_C +attr WR_0_KSEM obj-h40095-type INT16_VA +attr WR_0_KSEM obj-h40096-reading M_AC_VA_SF +attr WR_0_KSEM obj-h40096-type INT16 +attr WR_0_KSEM obj-h40097-reading M_AC_VAR +attr WR_0_KSEM obj-h40097-type INT16_VAR +attr WR_0_KSEM obj-h40098-reading M_AC_VAR_A +attr WR_0_KSEM obj-h40098-type INT16_VAR +attr WR_0_KSEM obj-h40099-reading M_AC_VAR_B +attr WR_0_KSEM obj-h40099-type INT16_VAR +attr WR_0_KSEM obj-h40100-reading M_AC_VAR_C +attr WR_0_KSEM obj-h40100-type INT16_VAR +attr WR_0_KSEM obj-h40101-reading M_AC_VAR_SF +attr WR_0_KSEM obj-h40101-type INT16 +attr WR_0_KSEM obj-h40102-reading M_AC_PF +attr WR_0_KSEM obj-h40102-type INT16_PF +attr WR_0_KSEM obj-h40103-reading M_AC_PF_A +attr WR_0_KSEM obj-h40103-type INT16_PF +attr WR_0_KSEM obj-h40104-reading M_AC_PF_B +attr WR_0_KSEM obj-h40104-type INT16_PF +attr WR_0_KSEM obj-h40105-reading M_AC_PF_C +attr WR_0_KSEM obj-h40105-type INT16_PF +attr WR_0_KSEM obj-h40106-reading M_AC_PF_SF +attr WR_0_KSEM obj-h40106-type INT16 +attr WR_0_KSEM obj-h40108-reading M_Exported +attr WR_0_KSEM obj-h40108-type UINT32 +attr WR_0_KSEM obj-h40110-reading M_Exported_A +attr WR_0_KSEM obj-h40110-type UINT32 +attr WR_0_KSEM obj-h40112-reading M_Exported_B +attr WR_0_KSEM obj-h40112-type UINT32 +attr WR_0_KSEM obj-h40114-reading M_Exported_C +attr WR_0_KSEM obj-h40114-type UINT32 +attr WR_0_KSEM obj-h40116-reading M_Imported +attr WR_0_KSEM obj-h40116-type UINT32 +attr WR_0_KSEM obj-h40118-reading M_Imported_A +attr WR_0_KSEM obj-h40118-type UINT32 +attr WR_0_KSEM obj-h40120-reading M_Imported_B +attr WR_0_KSEM obj-h40120-type UINT32 +attr WR_0_KSEM obj-h40122-reading M_Imported_C +attr WR_0_KSEM obj-h40122-type UINT32 +attr WR_0_KSEM obj-h40125-reading M_Exported_VA +attr WR_0_KSEM obj-h40125-type UINT32 +attr WR_0_KSEM obj-h40127-reading M_Exported_VA_A +attr WR_0_KSEM obj-h40127-type UINT32 +attr WR_0_KSEM obj-h40129-reading M_Exported_VA_B +attr WR_0_KSEM obj-h40129-type UINT32 +attr WR_0_KSEM obj-h40131-reading M_Exported_VA_C +attr WR_0_KSEM obj-h40131-type UINT32 +attr WR_0_KSEM obj-h40133-reading M_Imported_VA +attr WR_0_KSEM obj-h40133-type UINT32 +attr WR_0_KSEM obj-h40135-reading M_Imported_VA_A +attr WR_0_KSEM obj-h40135-type UINT32 +attr WR_0_KSEM obj-h40137-reading M_Imported_VA_B +attr WR_0_KSEM obj-h40137-type UINT32 +attr WR_0_KSEM obj-h40139-reading M_Imported_VA_C +attr WR_0_KSEM obj-h40139-type UINT32 +attr WR_0_KSEM obj-h40982-reading Home_consumption +attr WR_0_KSEM obj-h40982-type INT32 +attr WR_0_KSEM obj-h512-format %.0f +attr WR_0_KSEM obj-h512-reading Active_energy+ +attr WR_0_KSEM obj-h512-type UINT64 +attr WR_0_KSEM obj-h516-format %.0f +attr WR_0_KSEM obj-h516-reading Active_energy- +attr WR_0_KSEM obj-h516-type UINT64 +attr WR_0_KSEM obj-h8192-reading ManufacturerID +attr WR_0_KSEM obj-h8192-type UINT16 +attr WR_0_KSEM obj-h8193-reading ProductID +attr WR_0_KSEM obj-h8193-type UINT16 +attr WR_0_KSEM obj-h8194-reading ProductVersion +attr WR_0_KSEM obj-h8194-type UINT16 +attr WR_0_KSEM obj-h8195-reading FirmwareVersion +attr WR_0_KSEM obj-h8195-type UINT16 +attr WR_0_KSEM obj-h8196-reading VendorName +attr WR_0_KSEM obj-h8196-type STR32 +attr WR_0_KSEM obj-h8212-reading Productname +attr WR_0_KSEM obj-h8212-type STR32 +attr WR_0_KSEM obj-h8228-reading SerialNumber +attr WR_0_KSEM obj-h8228-type STR32 +attr WR_0_KSEM obj-h8244-reading MeasuringInterval +attr WR_0_KSEM obj-h8244-type UINT16 +attr WR_0_KSEM room Strom->Photovoltaik +attr WR_0_KSEM sortby 140 +attr WR_0_KSEM userReadings M_AC_Current:M_AC_Current_.* { ReadingsVal($NAME,"M_AC_Current_A",0) + ReadingsVal($NAME,"M_AC_Current_B",0) + ReadingsVal($NAME,"M_AC_Current_C",0) } +attr WR_0_KSEM verbose 0 diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1.txt b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1.txt new file mode 100644 index 000000000..2bc706e38 --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1.txt @@ -0,0 +1,353 @@ +defmod WR_1 ModbusAttr 71 60 192.168.178.18:1502 TCP +attr WR_1 userattr obj-h208-format obj-h512-len obj-h515-len +attr WR_1 DbLogExclude .* +attr WR_1 DbLogInclude Act_state_of_charge,Actual_Battery_charge_-minus_or_discharge_-plus_P,Actual_Battery_charge_usable_P,Battery_Total.*,Battery_charge.*,Battery_gross.*,Battery_temperature,Battery_MaxChargePowerLimitAbs,Battery_.*SOC,P_DC1,P_DC2,Total_.*,Solar_Calculation,Solar_Calculation_fc0_4h,Solar_Calculation_fc0_day,Solar_Calculation_fc0_rest,Solar_Correction.*,Solar_Cloud,Solar_East_Covered,Solar_Rain,Solar_SolarRadiation,Solar_Temp,Solar_WR_.*,Solar_middayhigh.*,SW_.*,P_limit_from_EVU.* +attr WR_1 alias WR_1 +attr WR_1 alignTime 00:00 +attr WR_1 comment Version 2022.12.30 10:00\ +Kostal Plenticore 10 Plus mit BYD Speicher +attr WR_1 dev-h-combine 8 +attr WR_1 dev-h-defFormat %.2f +attr WR_1 dev-h-defLen 2 +attr WR_1 dev-h-defPoll 1 +attr WR_1 dev-h-defRevRegs 1 +attr WR_1 dev-h-defUnpack f> +attr WR_1 dev-type-STR-format %s +attr WR_1 dev-type-STR-len 8 +attr WR_1 dev-type-STR-revRegs 0 +attr WR_1 dev-type-STR-unpack a* +attr WR_1 disable 0 +attr WR_1 event-on-change-reading Act_state_of_charge,Actual_Battery_charge_-minus_or_discharge_-plus_I,Actual_Battery_charge_-minus_or_discharge_-plus_P,Actual_Battery_charge_usable_P,Battery_Total.*,Battery_charge.*,Battery_gross.*,Battery_temperature,Battery_MaxChargePowerLimitAbs,Battery_.*SOC,Home_own_consumption.*,P_DC1,P_DC2,Solar_.*,Total_.*,SW_.*,.*_yield,Inverter_state.*,Inverter_Generation_P_Actual.*,Solar_Calculation_fc.*_day +attr WR_1 event-on-update-reading P_limit_from_EVU.* +attr WR_1 group PV Eigenverbrauch +attr WR_1 icon sani_solar +attr WR_1 obj-h100-reading Total_DC_P +attr WR_1 obj-h1024-len 1 +attr WR_1 obj-h1024-reading Battery_Charge_AC_P_Setpoint +attr WR_1 obj-h1024-set 1 +attr WR_1 obj-h1024-unpack n +attr WR_1 obj-h1025-len 1 +attr WR_1 obj-h1025-reading Battery_P_ScaleFactor +attr WR_1 obj-h1025-unpack n +attr WR_1 obj-h1026-reading Battery_Charge_AC_P_SetpointAbs +attr WR_1 obj-h1026-set 1 +attr WR_1 obj-h1028-reading Battery_Charge_DC_I_SetpointRel +attr WR_1 obj-h1028-set 1 +attr WR_1 obj-h1030-reading Battery_Charge_AC_P_SetpointRel +attr WR_1 obj-h1030-set 1 +attr WR_1 obj-h1032-reading Battery_Charge_DC_I_SetpointAbs +attr WR_1 obj-h1032-set 1 +attr WR_1 obj-h1034-reading Battery_Charge_DC_P_SetpointAbs +attr WR_1 obj-h1034-set 1 +attr WR_1 obj-h1036-reading Battery_Charge_DC_P_SetpointRel +attr WR_1 obj-h1036-set 1 +attr WR_1 obj-h1038-reading Battery_MaxChargePowerLimitAbs +attr WR_1 obj-h1038-set 1 +attr WR_1 obj-h104-format %s +attr WR_1 obj-h104-map 0:Normal,8:Ruhe1,16:Ruhe2,32:Ausgleichsladung,64:Tiefentladeschutz,256:externe Batteriesteuerung +attr WR_1 obj-h104-reading State_of_EM +attr WR_1 obj-h104-revRegs 0 +attr WR_1 obj-h104-unpack N +attr WR_1 obj-h1040-reading Battery_MaxDischargePowerLimitAbs +attr WR_1 obj-h1040-set 1 +attr WR_1 obj-h1042-reading Battery_MinSOC +attr WR_1 obj-h1042-set 1 +attr WR_1 obj-h1044-reading Battery_MaxSOC +attr WR_1 obj-h1044-set 1 +attr WR_1 obj-h1046-reading Battery_Total_DC_ChargeEnergy_DCsideToBattery +attr WR_1 obj-h1048-reading Battery_Total_DC_DischargeEnergy_DCsideFromBattery +attr WR_1 obj-h1050-reading Battery_Total_AC_ChargeEnergy_ACsideToBattery +attr WR_1 obj-h1052-reading Battery_Total_AC_DischargeEnergy_BatteryToGrid +attr WR_1 obj-h1054-reading Battery_Total_AC_ChargeEnergy_gridToBattery +attr WR_1 obj-h1056-reading Total_DC_PV_Energy_sumOfAllPVInputs +attr WR_1 obj-h1058-reading Total_DC_Energy_From_PV1 +attr WR_1 obj-h106-reading Home_own_consumption_from_Battery +attr WR_1 obj-h1060-reading Total_DC_Energy_From_PV2 +attr WR_1 obj-h1062-reading Total_DC_Energy_From_PV3 +attr WR_1 obj-h1064-reading Total_AC_Energy_ACsideToGrid +attr WR_1 obj-h1066-reading Total_DC_P_sumOfAllPVInputs +attr WR_1 obj-h1068-reading Battery_work_capacity +attr WR_1 obj-h1070-reading Battery_serial_number +attr WR_1 obj-h1072-reading Battery_Reserved_1072 +attr WR_1 obj-h1074-reading Battery_Reserved_1074 +attr WR_1 obj-h1076-reading Battery_Maximum_ChargePLimit_read-outFromBattery +attr WR_1 obj-h1078-reading Battery_Maximum_DischargePLimit_read-outFromBattery +attr WR_1 obj-h108-reading Home_own_consumption_from_grid +attr WR_1 obj-h1080-reading Battery_management_mode +attr WR_1 obj-h1080-set 1 +attr WR_1 obj-h1081-reading Battery_Reserved_1081 +attr WR_1 obj-h1082-reading Installed_sensor_type +attr WR_1 obj-h110-reading Total_home_consumption_Battery +attr WR_1 obj-h112-reading Total_home_consumption_Grid +attr WR_1 obj-h114-reading Total_home_consumption_PV +attr WR_1 obj-h116-reading Home_own_consumption_from_PV +attr WR_1 obj-h118-reading Total_home_consumption +attr WR_1 obj-h120-reading Isolation_resistance +attr WR_1 obj-h122-reading P_limit_from_EVU +attr WR_1 obj-h124-reading Total_home_consumption_rate +attr WR_1 obj-h14-reading Inverter_serial_number +attr WR_1 obj-h14-type STR +attr WR_1 obj-h144-reading Worktime +attr WR_1 obj-h150-reading Actual_cos_phi +attr WR_1 obj-h152-reading Grid_frequency +attr WR_1 obj-h154-reading I_L1 +attr WR_1 obj-h156-reading Active_P_L1 +attr WR_1 obj-h158-reading U_L1 +attr WR_1 obj-h160-reading I_L2 +attr WR_1 obj-h162-reading Active_P_L2 +attr WR_1 obj-h164-reading U_L2 +attr WR_1 obj-h166-reading I_L3 +attr WR_1 obj-h168-reading Active_P_L3 +attr WR_1 obj-h170-reading U_L3 +attr WR_1 obj-h172-reading Total_AC_Active_P +attr WR_1 obj-h174-reading Total_AC_Reactive_P +attr WR_1 obj-h178-reading Total_AC_Apparent_P +attr WR_1 obj-h190-reading Battery_charge_current +attr WR_1 obj-h194-format %.0f +attr WR_1 obj-h194-reading Number_of_Battery_cycles +attr WR_1 obj-h200-reading Actual_Battery_charge_-minus_or_discharge_-plus_I +attr WR_1 obj-h202-reading PSSB_fuse_state +attr WR_1 obj-h208-reading Battery_ready_flag +attr WR_1 obj-h210-reading Act_state_of_charge +attr WR_1 obj-h212-reading Battery_state +attr WR_1 obj-h214-reading Battery_temperature +attr WR_1 obj-h216-reading Battery_voltage +attr WR_1 obj-h218-reading Cos_phi_EM +attr WR_1 obj-h220-reading Frequency_EM +attr WR_1 obj-h222-reading I_L1_EM +attr WR_1 obj-h224-reading Active_P_L1_EM +attr WR_1 obj-h226-reading Reactive_P_L1_EM +attr WR_1 obj-h228-reading Apparent_P_L1_EM +attr WR_1 obj-h230-reading U_L1_EM +attr WR_1 obj-h232-reading I_L2_EM +attr WR_1 obj-h234-reading Active_P_L2_EM +attr WR_1 obj-h236-reading Reactive_P_L2_EM +attr WR_1 obj-h238-reading Apparent_P_L2_EM +attr WR_1 obj-h240-reading U_L2_EM +attr WR_1 obj-h242-reading I_L3_EM +attr WR_1 obj-h244-reading Active_P_L3_EM +attr WR_1 obj-h246-reading Reactive_P_L3_EM +attr WR_1 obj-h248-reading Apparent_P_L3_EM +attr WR_1 obj-h250-reading U_L3_EM +attr WR_1 obj-h252-reading Total_Active_P_EM +attr WR_1 obj-h254-reading Total_Reactive_P_EM +attr WR_1 obj-h256-reading Total_Apparent_P_EM +attr WR_1 obj-h258-reading I_DC1 +attr WR_1 obj-h260-reading P_DC1 +attr WR_1 obj-h266-reading U_DC1 +attr WR_1 obj-h268-reading I_DC2 +attr WR_1 obj-h270-reading P_DC2 +attr WR_1 obj-h276-reading U_DC2 +attr WR_1 obj-h278-reading I_DC3 +attr WR_1 obj-h280-reading P_DC3 +attr WR_1 obj-h286-reading U_DC3 +attr WR_1 obj-h320-reading Total_yield +attr WR_1 obj-h322-reading Daily_yield +attr WR_1 obj-h324-reading Yearly_yield +attr WR_1 obj-h326-reading Monthly_yield +attr WR_1 obj-h38-reading Software-Version_Maincontroller_MC +attr WR_1 obj-h38-type STR +attr WR_1 obj-h384-len 16 +attr WR_1 obj-h384-reading Inverter_network_name +attr WR_1 obj-h384-type STR +attr WR_1 obj-h4-format %.0f +attr WR_1 obj-h4-len 1 +attr WR_1 obj-h4-reading MODBUS_Unit-ID +attr WR_1 obj-h4-revRegs 1 +attr WR_1 obj-h4-unpack N +attr WR_1 obj-h420-reading IP-address +attr WR_1 obj-h420-type STR +attr WR_1 obj-h428-reading IP-subnetmask +attr WR_1 obj-h428-type STR +attr WR_1 obj-h436-reading IP-gateway +attr WR_1 obj-h436-type STR +attr WR_1 obj-h446-reading IP-DNS1 +attr WR_1 obj-h446-type STR +attr WR_1 obj-h454-reading IP-DNS2 +attr WR_1 obj-h454-type STR +attr WR_1 obj-h46-reading Software-Version_IO-Controller_IOC +attr WR_1 obj-h46-type STR +attr WR_1 obj-h5-format %.0f +attr WR_1 obj-h5-len 1 +attr WR_1 obj-h5-reading MODBUS_Byte_Order_Note +attr WR_1 obj-h5-revRegs 1 +attr WR_1 obj-h5-unpack N +attr WR_1 obj-h512-format %s +attr WR_1 obj-h512-reading Battery_gross_capacity +attr WR_1 obj-h512-unpack N +attr WR_1 obj-h514-len 1 +attr WR_1 obj-h514-reading Battery_Actual_SOC +attr WR_1 obj-h514-unpack n +attr WR_1 obj-h515-format %s +attr WR_1 obj-h515-reading Battery_Maincontroller_MC +attr WR_1 obj-h515-unpack N +attr WR_1 obj-h517-reading Battery_Manufacturer +attr WR_1 obj-h517-type STR +attr WR_1 obj-h525-format %s +attr WR_1 obj-h525-reading Battery_Model_ID +attr WR_1 obj-h525-unpack N +attr WR_1 obj-h527-format %s +attr WR_1 obj-h527-reading Battery_Serial_Number +attr WR_1 obj-h527-unpack N +attr WR_1 obj-h529-len 4 +attr WR_1 obj-h529-reading Work_Capacity +attr WR_1 obj-h529-unpack N +attr WR_1 obj-h531-format %.0f +attr WR_1 obj-h531-reading Inverter_Max_P +attr WR_1 obj-h531-unpack N +attr WR_1 obj-h56-format %.0f +attr WR_1 obj-h56-reading Inverter_state +attr WR_1 obj-h56-unpack N +attr WR_1 obj-h575-reading Inverter_Generation_P_Actual +attr WR_1 obj-h575-unpack N +attr WR_1 obj-h577-reading Generation_Energy +attr WR_1 obj-h577-unpack N +attr WR_1 obj-h578-reading Total_energy +attr WR_1 obj-h582-reading Actual_Battery_charge-discharge_P +attr WR_1 obj-h586-format %s +attr WR_1 obj-h586-reading Battery_Firmware +attr WR_1 obj-h586-unpack N +attr WR_1 obj-h6-reading Inverter_Article_number +attr WR_1 obj-h6-type STR +attr WR_1 obj-h768-len 32 +attr WR_1 obj-h768-reading Productname +attr WR_1 obj-h768-type STR +attr WR_1 obj-h800-len 32 +attr WR_1 obj-h800-reading Power_class +attr WR_1 obj-h800-type STR +attr WR_1 room Strom->Photovoltaik +attr WR_1 sortby 111 +attr WR_1 stateFormat {\ +if (AttrVal("$name","verbose",0) >=3) {\ + my $DUMMY = "";;\ +\ + my $Power = ReadingsVal($name,"Actual_Battery_charge_-minus_or_discharge_-plus_P",0);;\ + my $StatusSpeicher = ($Power < -10) ? "Laden" : ($Power > 15)? "Entladen" : "Standby";;\ + $StatusSpeicher = $StatusSpeicher."
".ReadingsVal($name,"State_of_EM","n/a");;\ + $Power = $Power." W";;\ +\ +\ + my $Battery_temperature = sprintf("%.1f °C",ReadingsVal($name,"Battery_temperature",0));;\ + $Battery_temperature = ((ReadingsVal("WR_1_API","DigitalOutputs_ConfigurationFlags",0) == 9) ? "Lüfter An
" : "
").$Battery_temperature;;\ +\ + my $Actual_Battery_charge_usable_P = sprintf("%d Wh",ReadingsVal($name,"Actual_Battery_charge_usable_P",0));;\ + \ + my $Act_state_of_charge = sprintf("%d %%",ReadingsVal($name,"Act_state_of_charge","0"));;\ + my $SW_Total_DC_P_sumOfAllPVInputs = sprintf("%d W",ReadingsVal($name,"SW_Total_DC_P_sumOfAllPVInputs","0"));;\ + my $SW_Total_PV_P_reserve = sprintf("%d W",ReadingsVal($name,"SW_Total_PV_P_reserve","0"));;\ +\ + my $SW_Home_own_consumption_from_PV = sprintf("%d",ReadingsVal($name,"SW_Home_own_consumption_from_PV",0));;\ + $SW_Home_own_consumption_from_PV = ($SW_Home_own_consumption_from_PV >= 0) ? $SW_Home_own_consumption_from_PV." W" : "0 W";;\ + my $SW_Home_own_consumption_from_Battery = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption_from_Battery",0));;\ + my $SW_Home_own_consumption_from_grid = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption_from_grid",0));;\ + my $SW_Home_own_consumption = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption",0));;\ +\ + my $Total_Active_P_EM = sprintf("%d",ReadingsVal($name,"Total_Active_P_EM",0));;\ + my $StatusNetz = ($Total_Active_P_EM < -10) ? "Einspeisen" : ($Total_Active_P_EM > 15)? "Netzbezug" : "Standby";;\ + $Total_Active_P_EM = $Total_Active_P_EM." W";;\ + \ + my $SW_Yield_Daily = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Daily",0)/1000 ,0));;\ + my $SW_Yield_Monthly = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Monthly",0)/1000 ,0));;\ + my $SW_Yield_Yearly = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Yearly",0)/1000 ,0));;\ + my $SW_Yield_Total = sprintf("%d MWh",round(ReadingsVal($name,"SW_Yield_Total",0)/1000/1000 ,0));;\ +\ + my $Solar_Calculation_fc0_4h = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_4h",0)/1000 ,0));;\ + my $Solar_Calculation_fc0_day = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_day",0)/1000 ,0));;\ + my $Solar_Calculation_fc0_rest = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_rest",0)/1000 ,0));;\ +\ +"\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
Wechselrichter / KSEM
Max DC / PV Reserve / Netz Leistung

".$SW_Total_DC_P_sumOfAllPVInputs."

".$SW_Total_PV_P_reserve."
".$StatusNetz."
".$Total_Active_P_EM."
Leistung
von PV / von Batterie / vom Netz / ins Haus

".$SW_Home_own_consumption_from_PV."

".$SW_Home_own_consumption_from_Battery."

".$SW_Home_own_consumption_from_grid."

".$SW_Home_own_consumption."
Ertrag
Tag / Monat / Jahr / Total

".$SW_Yield_Daily."

".$SW_Yield_Monthly."

".$SW_Yield_Yearly."

".$SW_Yield_Total."
Prognose
Tag / 4 Stunden / Resttag

".$Solar_Calculation_fc0_day."

".$Solar_Calculation_fc0_4h."

".$Solar_Calculation_fc0_rest."

".$DUMMY."
Speicher
Temperatur / nutzbare Ladung / Status / Leistung / akt. SOC
".$Battery_temperature."
".$Actual_Battery_charge_usable_P."
".$StatusSpeicher."
".$Power."
".$Act_state_of_charge."
\ +"\ +}\ +} +attr WR_1 userReadings Total_PV_P_reserve:Total_DC_P.* {my $reserve = ReadingsVal($NAME,"Total_DC_P_sumOfAllPVInputs",0) * 0.90 - ReadingsVal($NAME,"Home_own_consumption_from_PV",0);;;; ($reserve lt 0)? 0 : round($reserve,0) },\ +\ +Actual_Battery_charge_-minus_or_discharge_-plus_P:[Battery_voltage|Actual_Battery_charge_-minus_or_discharge_-plus_I].* {round((ReadingsVal($NAME,"Actual_Battery_charge_-minus_or_discharge_-plus_I",0)*ReadingsVal($NAME,"Battery_voltage",0)),0)},\ +\ +Total_DC_P_Max:[Total_DC_P_sumOfAllPVInputs|Actual_Battery_charge_-minus_or_discharge_-plus_P].* { my $Bat_P = ReadingsVal($NAME,"Actual_Battery_charge_-minus_or_discharge_-plus_P",0);;;; ($Bat_P gt 0)? round(ReadingsVal($NAME,"Total_DC_P_sumOfAllPVInputs",0) + $Bat_P,0) : round(ReadingsVal($NAME,"Total_DC_P_sumOfAllPVInputs",0),0) },\ +\ +Actual_Battery_charge_usable_P:[Act_state_of_charge|Battery_MinSOC].* {my $x = (ReadingsVal($NAME,"Battery_work_capacity",0)*(ReadingsVal($NAME,"Act_state_of_charge",0)-ReadingsVal($NAME,"Battery_MinSOC",0))/100);;;; ($x lt 0)? 0 : round($x,0) },\ +\ +SW_Inverter_Generation_P_Actual:Inverter_Generation_P_Actual.* {round(ReadingsVal($NAME,"Inverter_Generation_P_Actual",0)+ReadingsVal("WR_2","Inverter_Generation_P_Actual",0),0) },\ +\ +SW_Home_own_consumption:[Total_Active_P_EM:|Total_AC_Active_P:].* {round(ReadingsVal($NAME,"Total_Active_P_EM",0)+ReadingsVal($NAME,"Total_AC_Active_P",0)+ReadingsVal("WR_2","Total_AC_Active_P",0),0)},\ +SW_Total_AC_Active_P:Total_AC_Active_P:.* {round(ReadingsVal($NAME,"Total_AC_Active_P",0)+ReadingsVal("WR_2","Total_AC_Active_P",0),0)},\ +\ +\ +SW_Total_DC_P:Total_DC_P:.* {round(ReadingsVal($NAME,"Total_DC_P",0)+ReadingsVal("WR_2","Total_DC_P",0),0) },\ +\ +SW_Total_DC_P_sumOfAllPVInputs:Total_DC_P_sumOfAllPVInputs.* {round(ReadingsVal($NAME,"Total_DC_P_sumOfAllPVInputs",0)+ReadingsVal("WR_2","Total_DC_P_sumOfAllPVInputs",0),0) },\ +\ +SW_Total_PV_P_reserve:SW_Total_DC_P_sumOfAllPVInputs.* {my $reserve = ReadingsVal($NAME,"SW_Total_DC_P_sumOfAllPVInputs",0) * 0.90 - ReadingsVal($NAME,"SW_Home_own_consumption",0);;;; ($reserve lt 0)? 0 : round($reserve,0) },\ +\ +SW_Total_DC_P_Max:SW_Total_DC_P_sumOfAllPVInputs.* { my $Bat_out = (ReadingsVal($NAME,"Actual_Battery_charge_-minus_or_discharge_-plus_I",0)*ReadingsVal($NAME,"Battery_voltage",0));;;; ($Bat_out gt 0)? round(ReadingsVal($NAME,"SW_Total_DC_P_sumOfAllPVInputs",0) + $Bat_out,0) : round(ReadingsVal($NAME,"SW_Total_DC_P_sumOfAllPVInputs",0),0) },\ +\ +SW_Yield_Daily:Daily_yield.* { round(ReadingsVal($NAME,"Daily_yield",0)+ReadingsVal("WR_2","Daily_yield",0),0) },\ +SW_Yield_Monthly:Monthly_yield.* { round(ReadingsVal($NAME,"Monthly_yield",0)+ReadingsVal("WR_2","Monthly_yield",0),0) },\ +SW_Yield_Yearly:Yearly_yield.* { round(ReadingsVal($NAME,"Yearly_yield",0)+ReadingsVal("WR_2","Yearly_yield",0),0) },\ +SW_Yield_Total:Total_yield.* monotonic { round(ReadingsVal($NAME,"Total_yield",0)+ReadingsVal("WR_2","Total_yield",0),0) },\ +\ +SW_Home_own_consumption_from_PV:[Total_Active_P_EM|SW_Home_own_consumption:|Home_own_consumption_from_grid|Home_own_consumption_from_Battery].* { (ReadingsVal($NAME,"Total_Active_P_EM",0) ge 0) ? ReadingsVal($NAME,"SW_Home_own_consumption",0) - ReadingsVal($NAME,"Home_own_consumption_from_grid",0) - ReadingsVal($NAME,"Home_own_consumption_from_Battery",0) : ReadingsVal($NAME,"SW_Home_own_consumption",0) - ReadingsVal($NAME,"Home_own_consumption_from_Battery",0);;;; },\ +\ +SW_Home_own_consumption_from_Battery:[SW_Home_own_consumption_from_PV|Home_own_consumption_from_Battery].* { ReadingsVal($NAME,"Home_own_consumption_from_Battery",0) },\ +SW_Home_own_consumption_from_grid:[SW_Home_own_consumption_from_PV|Home_own_consumption_from_grid].* { ReadingsVal($NAME,"Home_own_consumption_from_grid",0) },\ +\ +\ +SW_Battery_Total_AC_ChargeEnergy_ACsideToBattery:Battery_Total_AC_ChargeEnergy_ACsideToBattery.* monotonic { round(ReadingsVal($NAME,"Battery_Total_AC_ChargeEnergy_ACsideToBattery",0),0) },\ +SW_Battery_Total_AC_ChargeEnergy_gridToBattery:Battery_Total_AC_ChargeEnergy_gridToBattery.* monotonic { round(ReadingsVal($NAME,"Battery_Total_AC_ChargeEnergy_gridToBattery",0),0) },\ +SW_Battery_Total_AC_DischargeEnergy_BatteryToGrid:Battery_Total_AC_DischargeEnergy_BatteryToGrid.* monotonic { round(ReadingsVal($NAME,"Battery_Total_AC_DischargeEnergy_BatteryToGrid",0),0) },\ +SW_Battery_Total_DC_ChargeEnergy_DCsideToBattery:Battery_Total_DC_ChargeEnergy_DCsideToBattery.* monotonic { round(ReadingsVal($NAME,"Battery_Total_DC_ChargeEnergy_DCsideToBattery",0),0) },\ +SW_Battery_Total_DC_DischargeEnergy_DCsideFromBattery:Battery_Total_DC_DischargeEnergy_DCsideFromBattery.* monotonic { round(ReadingsVal($NAME,"Battery_Total_DC_DischargeEnergy_DCsideFromBattery",0),0) },\ +\ +SW_Total_AC_Energy_ACsideToGrid:Total_AC_Energy_ACsideToGrid.* monotonic { round(ReadingsVal($NAME,"Total_AC_Energy_ACsideToGrid",0)+ReadingsVal("WR_2","Total_AC_Energy_ACsideToGrid",0),0) },\ +\ +SW_Total_DC_Energy_From_PV1:Total_DC_Energy_From_PV1.* monotonic { round(ReadingsVal($NAME,"Total_DC_Energy_From_PV1",0),0) },\ +SW_Total_DC_Energy_From_PV2:Total_DC_Energy_From_PV2.* monotonic { round(ReadingsVal($NAME,"Total_DC_Energy_From_PV2",0),0) },\ +SW_Total_DC_Energy_From_PV3:Total_DC_Energy_From_PV3.* monotonic { round(ReadingsVal($NAME,"Total_DC_Energy_From_PV3",0),0) },\ +SW_Total_DC_Energy_From_PV4:Total_DC_Energy_From_PV1.* monotonic { round(ReadingsVal("WR_2","Total_DC_Energy_From_PV1",0),0) },\ +SW_Total_DC_Energy_From_PV5:Total_DC_Energy_From_PV2.* monotonic { round(ReadingsVal("WR_2","Total_DC_Energy_From_PV2",0),0) },\ +SW_Total_DC_Energy_From_PV6:Total_DC_Energy_From_PV3.* monotonic { round(ReadingsVal("WR_2","Total_DC_Energy_From_PV3",0),0) },\ +SW_Total_DC_PV_Energy_sumOfAllPVInputs:Total_DC_PV_Energy_sumOfAllPVInputs.* monotonic { round(ReadingsVal($NAME,"Total_DC_PV_Energy_sumOfAllPVInputs",0)+ReadingsVal("WR_2","Total_DC_PV_Energy_sumOfAllPVInputs",0),0) },\ +SW_Total_home_consumption_Battery:Total_home_consumption_Battery.* monotonic { round(ReadingsVal($NAME,"Total_home_consumption_Battery",0),0) },\ +SW_Total_home_consumption_Grid:Total_home_consumption_Grid.* monotonic { round(ReadingsVal($NAME,"Total_home_consumption_Grid",0),0) },\ +SW_Total_home_consumption_PV:Total_home_consumption_PV.* monotonic { round(ReadingsVal($NAME,"Total_home_consumption_PV",0),0) },\ +\ +string_1_covered_snow:SW_Total_DC_Energy_From_PV1.* {\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);;;; $year += 1900;;;; $mon += 1 ;;;;\ + (($mon <= 2 or $mon >= 11) and\ + ($hour >= 9 and $hour <= 16) and\ + ReadingsVal($NAME,"P_DC1","10000") < 100 and\ + ReadingsVal("Heizung","ambientTemperature",100) < 10)? "Schnee" : "frei";;;; },\ +string_2_covered_snow:SW_Total_DC_Energy_From_PV2.* {\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);;;; $year += 1900;;;; $mon += 1 ;;;;\ + (($mon <= 2 or $mon >= 11) and\ + ($hour >= 9 and $hour <= 16) and\ + ReadingsVal($NAME,"P_DC2","10000") < 100 and\ + ReadingsVal("Heizung","ambientTemperature",100) < 10)? "Schnee" : "frei";;;; },\ +string_4_covered_snow:SW_Total_DC_Energy_From_PV4.* {\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);;;; $year += 1900;;;; $mon += 1 ;;;;\ + (($mon <= 2 or $mon >= 11) and\ + ($hour >= 9 and $hour <= 16) and\ + ReadingsVal("WR_2","P_DC1","10000") < 200 and\ + ReadingsVal("Heizung","ambientTemperature",100) < 10)? "Schnee" : "frei";;;; },\ +string_5_covered_snow:SW_Total_DC_Energy_From_PV5.* {\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);;;; $year += 1900;;;; $mon += 1 ;;;;\ + (($mon <= 2 or $mon >= 11) and\ + ($hour >= 9 and $hour <= 16) and\ + ReadingsVal("WR_2","P_DC2","10000") < 100 and\ + ReadingsVal("Heizung","ambientTemperature",100) < 10)? "Schnee" : "frei";;;; }\ + +attr WR_1 verbose 0 \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1_API.txt b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1_API.txt new file mode 100644 index 000000000..0f64ab077 --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1_API.txt @@ -0,0 +1,854 @@ +defmod WR_1_API HTTPMOD http://%IP-WR%/api/v1/auth/me 0 +attr WR_1_API userattr get25-1Name get25JSON get25Regex +attr WR_1_API DbLogExclude .* +attr WR_1_API DbLogInclude Statistic_Autarky.*,Statistic_Energy.*,Statistic_Own.*,Statistic_Total.*,Statistic_Yield.*,SW_.* +attr WR_1_API authRetries 1 +attr WR_1_API comment Version 2022.03.29 09:00\ +Passworte für die Abfrage des WR_1_API werden im storeKeyValue abgelegt:\ + {KeyValue("[read|store]","PW__","")}\ + {KeyValue("store","PW_WR_1_API_user","")} +attr WR_1_API disable 0 +attr WR_1_API dontRequeueAfterAuth 0 +attr WR_1_API enableControlSet 0 +attr WR_1_API enableCookies 1 +attr WR_1_API event-on-change-reading Battery_.*,DigitalOutputs_ConfigurationFlags +attr WR_1_API event-on-update-reading auth_.*,Statistic_Autarky.*,Statistic_EnergyFeedIn.*,Statistic_EnergyHome.*,Statistic_EnergyPv[1|2].*,Statistic_.*Consumption.*,Statistic_Energy.*_Total,Statistic_Yield.*,SW_.* +attr WR_1_API get01Data %START% +attr WR_1_API get01Name 01_auth_start +attr WR_1_API get01URL http://%IP-WR%/api/v1/auth/start +attr WR_1_API get02Data %FINISH% +attr WR_1_API get02Name 02_auth_finish +attr WR_1_API get02URL http://%IP-WR%/api/v1/auth/finish +attr WR_1_API get03Data %SESSION% +attr WR_1_API get03Name 03_auth_create_session +attr WR_1_API get03URL http://%IP-WR%/api/v1/auth/create_session +attr WR_1_API get04-1Name auth_me_active +attr WR_1_API get04-2Name auth_me_locked +attr WR_1_API get04-3Name auth_me_authenticated +attr WR_1_API get04-4Name auth_me_anonymous +attr WR_1_API get04-5Name auth_me_role +attr WR_1_API get04-6Name auth_me_permissions +attr WR_1_API get04Header authorization: Session %auth_sessionId% +attr WR_1_API get04JSON . +attr WR_1_API get04Name 04_auth_me +attr WR_1_API get04URL http://%IP-WR%/api/v1/auth/me +attr WR_1_API get05-1Name info_api_version +attr WR_1_API get05-2Name info_hostname +attr WR_1_API get05-3Name info_name +attr WR_1_API get05-4Name info_sw_version +attr WR_1_API get05JSON . +attr WR_1_API get05Name 05_info_version +attr WR_1_API get05URL http://%IP-WR%/api/v1/info/version +attr WR_1_API get20-10Format %.2f +attr WR_1_API get20-10Name Statistic_EnergyChargeGrid_Month +attr WR_1_API get20-11Format %.2f +attr WR_1_API get20-11Name Statistic_EnergyChargeGrid_Total +attr WR_1_API get20-12Format %.2f +attr WR_1_API get20-12Name Statistic_EnergyChargeGrid_Year +attr WR_1_API get20-13Format %.2f +attr WR_1_API get20-13Name Statistic_EnergyChargeInvIn_Day +attr WR_1_API get20-14Format %.2f +attr WR_1_API get20-14Name Statistic_EnergyChargeInvIn_Month +attr WR_1_API get20-15Format %.2f +attr WR_1_API get20-15Name Statistic_EnergyChargeInvIn_Total +attr WR_1_API get20-16Format %.2f +attr WR_1_API get20-16Name Statistic_EnergyChargeInvIn_Year +attr WR_1_API get20-17Format %.2f +attr WR_1_API get20-17Name Statistic_EnergyChargePv_Day +attr WR_1_API get20-18Format %.2f +attr WR_1_API get20-18Name Statistic_EnergyChargePv_Month +attr WR_1_API get20-19Format %.2f +attr WR_1_API get20-19Name Statistic_EnergyChargePv_Total +attr WR_1_API get20-1Format %.2f +attr WR_1_API get20-1Name Statistic_Autarky_Day +attr WR_1_API get20-20Format %.2f +attr WR_1_API get20-20Name Statistic_EnergyChargePv_Year +attr WR_1_API get20-21Format %.2f +attr WR_1_API get20-21Name Statistic_EnergyDischarge_Day +attr WR_1_API get20-22Format %.2f +attr WR_1_API get20-22Name Statistic_EnergyDischarge_Month +attr WR_1_API get20-23Format %.2f +attr WR_1_API get20-23Name Statistic_EnergyDischarge_Total +attr WR_1_API get20-24Format %.2f +attr WR_1_API get20-24Name Statistic_EnergyDischarge_Year +attr WR_1_API get20-25Format %.2f +attr WR_1_API get20-25Name Statistic_EnergyDischargeGrid_Day +attr WR_1_API get20-26Format %.2f +attr WR_1_API get20-26Name Statistic_EnergyDischargeGrid_Month +attr WR_1_API get20-27Format %.2f +attr WR_1_API get20-27Name Statistic_EnergyDischargeGrid_Total +attr WR_1_API get20-28Format %.2f +attr WR_1_API get20-28Name Statistic_EnergyDischargeGrid_Year +attr WR_1_API get20-29Format %.2f +attr WR_1_API get20-29Name Statistic_EnergyHome_Day +attr WR_1_API get20-2Format %.2f +attr WR_1_API get20-2Name Statistic_Autarky_Month +attr WR_1_API get20-30Format %.2f +attr WR_1_API get20-30Name Statistic_EnergyHome_Month +attr WR_1_API get20-31Format %.2f +attr WR_1_API get20-31Name Statistic_EnergyHome_Total +attr WR_1_API get20-32Format %.2f +attr WR_1_API get20-32Name Statistic_EnergyHome_Year +attr WR_1_API get20-33Format %.2f +attr WR_1_API get20-33Name Statistic_EnergyHomeBat_Day +attr WR_1_API get20-34Format %.2f +attr WR_1_API get20-34Name Statistic_EnergyHomeBat_Month +attr WR_1_API get20-35Format %.2f +attr WR_1_API get20-35Name Statistic_EnergyHomeBat_Total +attr WR_1_API get20-36Format %.2f +attr WR_1_API get20-36Name Statistic_EnergyHomeBat_Year +attr WR_1_API get20-37Format %.2f +attr WR_1_API get20-37Name Statistic_EnergyHomeGrid_Day +attr WR_1_API get20-38Format %.2f +attr WR_1_API get20-38Name Statistic_EnergyHomeGrid_Month +attr WR_1_API get20-39Format %.2f +attr WR_1_API get20-39Name Statistic_EnergyHomeGrid_Total +attr WR_1_API get20-3Format %.2f +attr WR_1_API get20-3Name Statistic_Autarky_Total +attr WR_1_API get20-40Format %.2f +attr WR_1_API get20-40Name Statistic_EnergyHomeGrid_Year +attr WR_1_API get20-41Format %.2f +attr WR_1_API get20-41Name Statistic_EnergyHomeOwn_Total +attr WR_1_API get20-42Format %.2f +attr WR_1_API get20-42Name Statistic_EnergyHomePv_Day +attr WR_1_API get20-43Format %.2f +attr WR_1_API get20-43Name Statistic_EnergyHomePv_Month +attr WR_1_API get20-44Format %.2f +attr WR_1_API get20-44Name Statistic_EnergyHomePv_Total +attr WR_1_API get20-45Format %.2f +attr WR_1_API get20-45Name Statistic_EnergyHomePv_Year +attr WR_1_API get20-46Format %.2f +attr WR_1_API get20-46Name Statistic_EnergyPv1_Day +attr WR_1_API get20-47Format %.2f +attr WR_1_API get20-47Name Statistic_EnergyPv1_Month +attr WR_1_API get20-48Format %.2f +attr WR_1_API get20-48Name Statistic_EnergyPv1_Total +attr WR_1_API get20-49Format %.2f +attr WR_1_API get20-49Name Statistic_EnergyPv1_Year +attr WR_1_API get20-4Format %.2f +attr WR_1_API get20-4Name Statistic_Autarky_Year +attr WR_1_API get20-50Format %.2f +attr WR_1_API get20-50Name Statistic_EnergyPv2_Day +attr WR_1_API get20-51Format %.2f +attr WR_1_API get20-51Name Statistic_EnergyPv2_Month +attr WR_1_API get20-52Format %.2f +attr WR_1_API get20-52Name Statistic_EnergyPv2_Total +attr WR_1_API get20-53Format %.2f +attr WR_1_API get20-53Name Statistic_EnergyPv2_Year +attr WR_1_API get20-54Format %.2f +attr WR_1_API get20-54Name Statistic_EnergyPv3_Day +attr WR_1_API get20-55Format %.2f +attr WR_1_API get20-55Name Statistic_EnergyPv3_Month +attr WR_1_API get20-56Format %.2f +attr WR_1_API get20-56Name Statistic_EnergyPv3_Total +attr WR_1_API get20-57Format %.2f +attr WR_1_API get20-57Name Statistic_EnergyPv3_Year +attr WR_1_API get20-58Format %.2f +attr WR_1_API get20-58Name Statistic_OwnConsumptionRate_Day +attr WR_1_API get20-59Format %.2f +attr WR_1_API get20-59Name Statistic_OwnConsumptionRate_Month +attr WR_1_API get20-5Format %.2f +attr WR_1_API get20-5Name Statistic_CO2Saving_Day +attr WR_1_API get20-60Format %.2f +attr WR_1_API get20-60Name Statistic_OwnConsumptionRate_Total +attr WR_1_API get20-61Format %.2f +attr WR_1_API get20-61Name Statistic_OwnConsumptionRate_Year +attr WR_1_API get20-62Format %.2f +attr WR_1_API get20-62Name Statistic_Yield_Day +attr WR_1_API get20-63Format %.2f +attr WR_1_API get20-63Name Statistic_Yield_Month +attr WR_1_API get20-64Format %.2f +attr WR_1_API get20-64Name Statistic_Yield_Total +attr WR_1_API get20-65Format %.2f +attr WR_1_API get20-65Name Statistic_Yield_Year +attr WR_1_API get20-6Format %.2f +attr WR_1_API get20-6Name Statistic_CO2Saving_Month +attr WR_1_API get20-7Format %.2f +attr WR_1_API get20-7Name Statistic_CO2Saving_Total +attr WR_1_API get20-8Format %.2f +attr WR_1_API get20-8Name Statistic_CO2Saving_Year +attr WR_1_API get20-9Format %.2f +attr WR_1_API get20-9Name Statistic_EnergyChargeGrid_Day +attr WR_1_API get20Header authorization: Session %auth_sessionId% +attr WR_1_API get20JSON 01_processdata_.._value +attr WR_1_API get20Name 20_Statistic_EnergyFlow +attr WR_1_API get20URL http://%IP-WR%/api/v1/processdata/scb:statistic:EnergyFlow +attr WR_1_API get21-1Name Battery_Info_Cycles +attr WR_1_API get21-2Name Battery_Info_FullChargeCap_E +attr WR_1_API get21-3Name Battery_Info_SoC +attr WR_1_API get21-4Format %d +attr WR_1_API get21-4Name Battery_Info_WorkCapacity +attr WR_1_API get21Header01 authorization: Session %auth_sessionId% +attr WR_1_API get21Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API get21JSON .._processdata_.._value +attr WR_1_API get21Name 21_Battery_Information +attr WR_1_API get21URL http://%IP-WR%/api/v1/processdata/devices:local:battery/Cycles,FullChargeCap_E,SoC,WorkCapacity +attr WR_1_API get22-1Name Battery_InternControl_DynamicSoc_Enable +attr WR_1_API get22-2Name Battery_Control +attr WR_1_API get22-3Format %d +attr WR_1_API get22-3Name Battery_InternControl_MinHomeConsumption +attr WR_1_API get22-4Name Battery_InternControl_MinSoc +attr WR_1_API get22-5Name Battery_InternControl_SmartBatteryControl_Enable +attr WR_1_API get22-6Name Battery_InternControl_Strategy +attr WR_1_API get22-7Name Battery_InternControl_Type +attr WR_1_API get22Header01 authorization: Session %auth_sessionId% +attr WR_1_API get22Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API get22JSON .._value +attr WR_1_API get22Name 22_Battery_InternControl +attr WR_1_API get22URL http://%IP-WR%/api/v1/settings/devices:local/Battery:ExternControl,Battery:Type,Battery:MinHomeComsumption,Battery:Strategy,Battery:MinSoc,Battery:SmartBatteryControl:Enable,Battery:DynamicSoc:Enable,Battery:Type +attr WR_1_API get23-10Format %d +attr WR_1_API get23-10Name Battery_ExternControl_MaxChargePowerAbs +attr WR_1_API get23-11Format %d +attr WR_1_API get23-11Name Battery_ExternControl_MaxDischargePowerAbs +attr WR_1_API get23-12Format %d +attr WR_1_API get23-12Name Battery_ExternControl_MaxSocRel +attr WR_1_API get23-13Format %d +attr WR_1_API get23-13Name Battery_ExternControl_MinSocRel +attr WR_1_API get23-1Name Battery_ComMonitor_Enable +attr WR_1_API get23-2Format %d +attr WR_1_API get23-2Name Battery_ComMonitor_Time +attr WR_1_API get23-3Name Battery_Control +attr WR_1_API get23-4Format %.2f +attr WR_1_API get23-4Name Battery_ExternControl_AcPowerAbs +attr WR_1_API get23-5Format %.2f +attr WR_1_API get23-5Name Battery_ExternControl_AcPowerRel +attr WR_1_API get23-6Format %.2f +attr WR_1_API get23-6Name Battery_ExternControl_DcCurrentAbs +attr WR_1_API get23-7Format %.2f +attr WR_1_API get23-7Name Battery_ExternControl_DcCurrentRel +attr WR_1_API get23-8Format %.2f +attr WR_1_API get23-8Name Battery_ExternControl_DcPowerAbs +attr WR_1_API get23-9Format %.2f +attr WR_1_API get23-9Name Battery_ExternControl_DcPowerRel +attr WR_1_API get23Header01 authorization: Session %auth_sessionId% +attr WR_1_API get23Header02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_1_API get23JSON .._value +attr WR_1_API get23Name 23_Battery_ExternControl +attr WR_1_API get23URL http://%IP-WR%/api/v1/settings/devices:local/Battery:ComMonitor:Enable,Battery:ComMonitor:Time,Battery:ExternControl,Battery:ExternControl:AcPowerAbs,Battery:ExternControl:AcPowerRel,Battery:ExternControl:DcCurrentAbs,Battery:ExternControl:DcCurrentRel,Battery:ExternControl:DcPowerAbs,Battery:ExternControl:DcPowerRel,Battery:ExternControl:MaxChargePowerAbs,Battery:ExternControl:MaxDischargePowerAbs,Battery:ExternControl:MaxSocRel,Battery:ExternControl:MinSocRel +attr WR_1_API get24-1Name Battery_TimeControl_5 +attr WR_1_API get24-1OExpr my @x = ( $val =~ m/.{4}/g );; my $x = $x[0];;for(my $i = 1;;$i < @x;;$i++) { $x = $x." ".$x[$i]};; $x +attr WR_1_API get24-2Name Battery_TimeControl_1 +attr WR_1_API get24-2OExpr my @x = ( $val =~ m/.{4}/g );; my $x = $x[0];;for(my $i = 1;;$i < @x;;$i++) { $x = $x." ".$x[$i]};; $x +attr WR_1_API get24-3Name Battery_TimeControl_6 +attr WR_1_API get24-3OExpr my @x = ( $val =~ m/.{4}/g );; my $x = $x[0];;for(my $i = 1;;$i < @x;;$i++) { $x = $x." ".$x[$i]};; $x +attr WR_1_API get24-4Name Battery_TimeControl_0 +attr WR_1_API get24-4OExpr my @x = ( $val =~ m/.{4}/g );; my $x = $x[0];;for(my $i = 1;;$i < @x;;$i++) { $x = $x." ".$x[$i]};; $x +attr WR_1_API get24-5Name Battery_TimeControl_4 +attr WR_1_API get24-5OExpr my @x = ( $val =~ m/.{4}/g );; my $x = $x[0];;for(my $i = 1;;$i < @x;;$i++) { $x = $x." ".$x[$i]};; $x +attr WR_1_API get24-6Name Battery_TimeControl_2 +attr WR_1_API get24-6OExpr my @x = ( $val =~ m/.{4}/g );; my $x = $x[0];;for(my $i = 1;;$i < @x;;$i++) { $x = $x." ".$x[$i]};; $x +attr WR_1_API get24-7Name Battery_TimeControl_3 +attr WR_1_API get24-7OExpr my @x = ( $val =~ m/.{4}/g );; my $x = $x[0];;for(my $i = 1;;$i < @x;;$i++) { $x = $x." ".$x[$i]};; $x +attr WR_1_API get24-8Name Battery_TimeControl +attr WR_1_API get24Header01 authorization: Session %auth_sessionId% +attr WR_1_API get24Header02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_1_API get24JSON .._value +attr WR_1_API get24Name 24_Battery_TimeControl +attr WR_1_API get24URL http://%IP-WR%/api/v1/settings/devices:local/Battery:TimeControl:Enable,Battery:TimeControl:ConfMon,Battery:TimeControl:ConfTue,Battery:TimeControl:ConfWed,Battery:TimeControl:ConfThu,Battery:TimeControl:ConfFri,Battery:TimeControl:ConfSat,Battery:TimeControl:ConfSun +attr WR_1_API get25Header01 authorization: Session %auth_sessionId% +attr WR_1_API get25Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API get25Name 25_Battery_EM_State +attr WR_1_API get25URL http://%IP-WR%/api/v1/processdata/devices:local/EM_State +attr WR_1_API get40-1Name EnergyMgmt_AcStorage +attr WR_1_API get40-2Name Generator_ShadowMgmt +attr WR_1_API get40Header01 authorization: Session %auth_sessionId% +attr WR_1_API get40Header02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_1_API get40JSON .._value +attr WR_1_API get40Name 40_Generator_und_EnergieMgmt +attr WR_1_API get40URL http://%IP-WR%/api/v1/settings/devices:local/Generator:ShadowMgmt:Enable,EnergyMgmt:AcStorage +attr WR_1_API get41-1Name DigitalOutputs_ConfigurationFlags +attr WR_1_API get41-2Name DigitalOutputs_DelayTime +attr WR_1_API get41-3Name DigitalOutputs_PowerMode_OffPowerThreshold +attr WR_1_API get41-4Name DigitalOutputs_PowerMode_OnPowerThreshold +attr WR_1_API get41-5Name DigitalOutputs_SwitchOffDuration +attr WR_1_API get41-6Name DigitalOutputs_TimeMode_MaxNoOfSwitchingCyclesPerDay +attr WR_1_API get41-7Name DigitalOutputs_TimeMode_PowerThreshold +attr WR_1_API get41-8Name DigitalOutputs_TimeMode_RunTime +attr WR_1_API get41-9Name DigitalOutputs_TimeMode_StableTime +attr WR_1_API get41Header01 authorization: Session %auth_sessionId% +attr WR_1_API get41Header02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_1_API get41JSON .._value +attr WR_1_API get41Name 41_DigitalOutputs +attr WR_1_API get41URL http://%IP-WR%/api/v1/settings/devices:local/DigitalOutputs:Customer:ConfigurationFlags,DigitalOutputs:Customer:DelayTime,DigitalOutputs:Customer:PowerMode:OffPowerThreshold,DigitalOutputs:Customer:PowerMode:OnPowerThreshold,DigitalOutputs:Customer:SwitchOffDuration,DigitalOutputs:Customer:TimeMode:MaxNoOfSwitchingCyclesPerDay,DigitalOutputs:Customer:TimeMode:PowerThreshold,DigitalOutputs:Customer:TimeMode:RunTime,DigitalOutputs:Customer:TimeMode:StableTime +attr WR_1_API get51Name 51_modules_list +attr WR_1_API get51URL http://%IP-WR%/api/v1/modules +attr WR_1_API get59Data {"end":"%end_date%","begin":"%begin_date%"} +attr WR_1_API get59Header01 authorization: Session %auth_sessionId% +attr WR_1_API get59Header02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_1_API get59Name 59_logdata_download +attr WR_1_API get59URL http://%IP-WR%/api/v1/logdata/download +attr WR_1_API get60Header authorization: Session %auth_sessionId% +attr WR_1_API get60Name 60_update_status +attr WR_1_API get60URL http://%IP-WR%/api/v1/update/status +attr WR_1_API getHeader01 Accept-Encoding: gzip,deflate +attr WR_1_API getHeader02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API group PV Eigenverbrauch +attr WR_1_API icon sani_solar +attr WR_1_API reAuthRegex "authenticated":false|"processdata":\[\]|wrong credentials|Not authorized +attr WR_1_API reading0101JSON nonce +attr WR_1_API reading0101Name auth_nonce +attr WR_1_API reading0102JSON rounds +attr WR_1_API reading0102Name auth_rounds +attr WR_1_API reading0103JSON salt +attr WR_1_API reading0103Name auth_salt +attr WR_1_API reading0104JSON transactionId +attr WR_1_API reading0104Name auth_transactionId +attr WR_1_API reading0201JSON signature +attr WR_1_API reading0201Name auth_signature +attr WR_1_API reading0202JSON token +attr WR_1_API reading0202Name auth_token +attr WR_1_API reading0301JSON message +attr WR_1_API reading0301Name info_message +attr WR_1_API reading0302JSON error +attr WR_1_API reading0302Name info_error +attr WR_1_API reading03JSON sessionId +attr WR_1_API reading03Name auth_sessionId +attr WR_1_API reading25Name Battery_EM_State +attr WR_1_API reading25OMap 0:Normal,8:Ruhe1,16:Ruhe2,32:Ausgleichsladung,64:Tiefentladeschutz,256:externe Batteriesteuerung +attr WR_1_API reading25Regex EM_State.*value":(\d+) +attr WR_1_API reading40Name Generator_ShadowMgmt +attr WR_1_API reading40Regex Generator:ShadowMgmt.*value":"(\d+) +attr WR_1_API replacement01Mode text +attr WR_1_API replacement01Regex %IP-WR% +attr WR_1_API replacement01Value 192.168.178.18 +attr WR_1_API replacement02Mode expression +attr WR_1_API replacement02Regex %START% +attr WR_1_API replacement02Value {my $NAME="WR_1_API";; plenticore_auth("start","user","$NAME")} +attr WR_1_API replacement04Mode expression +attr WR_1_API replacement04Regex %FINISH% +attr WR_1_API replacement04Value {my $NAME="WR_1_API";; plenticore_auth("finish","user","$NAME",ReadingsVal("$NAME","auth_randomString64","missed"),ReadingsVal("$NAME","auth_nonce","missed"),ReadingsVal("$NAME","auth_salt","missed"),ReadingsVal("$NAME","auth_rounds","missed"),ReadingsVal("$NAME","auth_transactionId","missed"))} +attr WR_1_API replacement05Mode expression +attr WR_1_API replacement05Regex %SESSION% +attr WR_1_API replacement05Value {my $NAME="WR_1_API";; plenticore_auth("session","user","$NAME",ReadingsVal("$NAME","auth_randomString64","missed"),ReadingsVal("$NAME","auth_nonce","missed"),ReadingsVal("$NAME","auth_salt","missed"),ReadingsVal("$NAME","auth_rounds","missed"),ReadingsVal("$NAME","auth_transactionId","missed"),ReadingsVal("$NAME","auth_token","missed"))} +attr WR_1_API replacement06Mode reading +attr WR_1_API replacement06Regex %auth_signature% +attr WR_1_API replacement06Value auth_signature +attr WR_1_API replacement07Mode reading +attr WR_1_API replacement07Regex %auth_sessionId% +attr WR_1_API replacement07Value auth_sessionId +attr WR_1_API replacement08Mode expression +attr WR_1_API replacement08Regex %begin_date% +attr WR_1_API replacement08Value {POSIX::strftime("%Y-%m-%d",localtime(time))} +attr WR_1_API replacement09Mode expression +attr WR_1_API replacement09Regex %end_date% +attr WR_1_API replacement09Value {POSIX::strftime("%Y-%m-%d",localtime(time))} +attr WR_1_API room Strom->Photovoltaik +attr WR_1_API set06Header01 authorization: Session %auth_sessionId% +attr WR_1_API set06Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set06Method POST +attr WR_1_API set06Name 06_auth_logout +attr WR_1_API set06NoArg 1 +attr WR_1_API set06URL http://%IP-WR%/api/v1/auth/logout +attr WR_1_API set2201Data [{"moduleid":"devices:local","settings":[{"id":"Battery:DynamicSoc:Enable","value":"$val"}]}] +attr WR_1_API set2201FollowGet 22_Battery_InternControl +attr WR_1_API set2201Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2201Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2201Hint 0,1 +attr WR_1_API set2201Method PUT +attr WR_1_API set2201Name 22_01_Battery_DynamicSoc_Enable +attr WR_1_API set2201URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2203Data [{"moduleid":"devices:local","settings":[{"id":"Battery:MinHomeComsumption","value":"$val"}]}] +attr WR_1_API set2203FollowGet 22_Battery_InternControl +attr WR_1_API set2203Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2203Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2203Hint slider,50,50,8000 +attr WR_1_API set2203Method PUT +attr WR_1_API set2203Name 22_03_Battery_MinHomeConsumption +attr WR_1_API set2203URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2204Data [{"moduleid":"devices:local","settings":[{"id":"Battery:MinSoc","value":"$val"}]}] +attr WR_1_API set2204FollowGet 22_Battery_InternControl +attr WR_1_API set2204Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2204Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2204Hint slider,5,5,100 +attr WR_1_API set2204Method PUT +attr WR_1_API set2204Name 22_04_Battery_MinSoc +attr WR_1_API set2204URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2205Data [{"moduleid":"devices:local","settings":[{"id":"Battery:SmartBatteryControl:Enable","value":"$val"}]}] +attr WR_1_API set2205FollowGet 22_Battery_InternControl +attr WR_1_API set2205Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2205Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2205Hint 0,1 +attr WR_1_API set2205Method PUT +attr WR_1_API set2205Name 22_05_Battery_SmartBatteryControl_Enable +attr WR_1_API set2205URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2206Data [{"moduleid":"devices:local","settings":[{"id":"Battery:Strategy","value":"$val"}]}] +attr WR_1_API set2206FollowGet 22_Battery_InternControl +attr WR_1_API set2206Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2206Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2206Hint 1,2 +attr WR_1_API set2206Method PUT +attr WR_1_API set2206Name 22_06_Battery_Strategy +attr WR_1_API set2206URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2207Data [{"moduleid":"devices:local","settings":[{"id":"Battery:Type","value":"$val"}]}] +attr WR_1_API set2207FollowGet 22_Battery_InternControl +attr WR_1_API set2207Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2207Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2207Hint 0,4 +attr WR_1_API set2207Method PUT +attr WR_1_API set2207Name 22_07_Battery_Type +attr WR_1_API set2207URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2300Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl","value":"$val"}]}] +attr WR_1_API set2300FollowGet 23_Battery_ExternControl +attr WR_1_API set2300Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2300Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2300Hint 0,1,2 +attr WR_1_API set2300Method PUT +attr WR_1_API set2300Name 23_00_Battery_ExternControl +attr WR_1_API set2300URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2301Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:AcPowerAbs","value":"$val"}]}] +attr WR_1_API set2301FollowGet 23_Battery_ExternControl +attr WR_1_API set2301Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2301Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2301Method PUT +attr WR_1_API set2301Name 23_01_Battery_ExternControl_AcPowerAbs +attr WR_1_API set2301URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2302Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:AcPowerRel","value":"$val"}]}] +attr WR_1_API set2302FollowGet 23_Battery_ExternControl +attr WR_1_API set2302Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2302Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2302Method PUT +attr WR_1_API set2302Name 23_02_Battery_ExternControl_AcPowerRel +attr WR_1_API set2302URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2303Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:DcCurrentAbs","value":"$val"}]}] +attr WR_1_API set2303FollowGet 23_Battery_ExternControl +attr WR_1_API set2303Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2303Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2303Method PUT +attr WR_1_API set2303Name 23_03_Battery_ExternControl_DcCurrentAbs +attr WR_1_API set2303URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2304Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:DcCurrentRel","value":"$val"}]}] +attr WR_1_API set2304FollowGet 23_Battery_ExternControl +attr WR_1_API set2304Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2304Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2304Method PUT +attr WR_1_API set2304Name 23_04_Battery_ExternControl_DcCurrentRel +attr WR_1_API set2304URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2305Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:DcPowerAbs","value":"$val"}]}] +attr WR_1_API set2305FollowGet 23_Battery_ExternControl +attr WR_1_API set2305Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2305Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2305Method PUT +attr WR_1_API set2305Name 23_05_Battery_ExternControl_DcPowerAbs +attr WR_1_API set2305URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2306Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:DcPowerRel","value":"$val"}]}] +attr WR_1_API set2306FollowGet 23_Battery_ExternControl +attr WR_1_API set2306Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2306Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2306Method PUT +attr WR_1_API set2306Name 23_06_Battery_ExternControl_DcPowerRel +attr WR_1_API set2306URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2307Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:MaxChargePowerAbs","value":"$val"}]}] +attr WR_1_API set2307FollowGet 23_Battery_ExternControl +attr WR_1_API set2307Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2307Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2307Method PUT +attr WR_1_API set2307Name 23_07_Battery_ExternControl_MaxChargePowerAbs +attr WR_1_API set2307URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2308Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:MaxDischargePowerAbs","value":"$val"}]}] +attr WR_1_API set2308FollowGet 23_Battery_ExternControl +attr WR_1_API set2308Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2308Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2308Method PUT +attr WR_1_API set2308Name 23_08_Battery_ExternControl_MaxDischargePowerAbs +attr WR_1_API set2308URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2309Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:MaxSocRel","value":"$val"}]}] +attr WR_1_API set2309FollowGet 23_Battery_ExternControl +attr WR_1_API set2309Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2309Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2309Hint slider,30,5,100 +attr WR_1_API set2309Method PUT +attr WR_1_API set2309Name 23_09_Battery_ExternControl_MaxSocRel +attr WR_1_API set2309URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2310Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ExternControl:MinSocRel","value":"$val"}]}] +attr WR_1_API set2310FollowGet 23_Battery_ExternControl +attr WR_1_API set2310Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2310Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2310Hint slider,0,5,100 +attr WR_1_API set2310Method PUT +attr WR_1_API set2310Name 23_10_Battery_ExternControl_MinSocRel +attr WR_1_API set2310URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2311Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ComMonitor:Enable","value":"$val"}]}] +attr WR_1_API set2311FollowGet 23_Battery_ExternControl +attr WR_1_API set2311Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2311Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2311Hint 0,1 +attr WR_1_API set2311Method PUT +attr WR_1_API set2311Name 23_11_Battery_ComMonitor_Enable +attr WR_1_API set2311URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2312Data [{"moduleid":"devices:local","settings":[{"id":"Battery:ComMonitor:Time","value":"$val"}]}] +attr WR_1_API set2312FollowGet 23_Battery_ExternControl +attr WR_1_API set2312Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2312Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2312Hint slider,0,10,600 +attr WR_1_API set2312Method PUT +attr WR_1_API set2312Name 23_12_Battery_ComMonitor_Time +attr WR_1_API set2312URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2400Data [{"moduleid":"devices:local","settings":[{"id":"Battery:TimeControl:Enable","value":"$val"}]}] +attr WR_1_API set2400FollowGet 24_Battery_TimeControl +attr WR_1_API set2400Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2400Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2400Hint 0,1 +attr WR_1_API set2400Method PUT +attr WR_1_API set2400Name 24_00_Battery_TimeControl +attr WR_1_API set2400URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2401Data [{"moduleid":"devices:local","settings":[{"id":"Battery:TimeControl:ConfSun","value":"$val"}]}] +attr WR_1_API set2401FollowGet 24_Battery_TimeControl +attr WR_1_API set2401Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2401Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2401Hint 0,1,2,Battery_TimeControl_0_So +attr WR_1_API set2401IExpr my $x = ReadingsVal($name,$val,"null");; $x=~s/\s//gs;; ($val =~ /^-?\d+$/)? $val x96 : ($x =~ /^-?\d+$/)? $x : 0 x96 +attr WR_1_API set2401Method PUT +attr WR_1_API set2401Name 24__0_Battery_TimeControl_So +attr WR_1_API set2401URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2402Data [{"moduleid":"devices:local","settings":[{"id":"Battery:TimeControl:ConfMon","value":"$val"}]}] +attr WR_1_API set2402FollowGet 24_Battery_TimeControl +attr WR_1_API set2402Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2402Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2402Hint 0,1,2,Battery_TimeControl_1_Mo +attr WR_1_API set2402IExpr my $x = ReadingsVal($name,$val,"null");; $x=~s/\s//gs;; ($val =~ /^-?\d+$/)? $val x96 : ($x =~ /^-?\d+$/)? $x : 0 x96 +attr WR_1_API set2402Method PUT +attr WR_1_API set2402Name 24__1_Battery_TimeControl_Mo +attr WR_1_API set2402URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2403Data [{"moduleid":"devices:local","settings":[{"id":"Battery:TimeControl:ConfTue","value":"$val"}]}] +attr WR_1_API set2403FollowGet 24_Battery_TimeControl +attr WR_1_API set2403Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2403Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2403Hint 0,1,2,Battery_TimeControl_2_Di +attr WR_1_API set2403IExpr my $x = ReadingsVal($name,$val,"null");; $x=~s/\s//gs;; ($val =~ /^-?\d+$/)? $val x96 : ($x =~ /^-?\d+$/)? $x : 0 x96 +attr WR_1_API set2403Method PUT +attr WR_1_API set2403Name 24__2_Battery_TimeControl_Di +attr WR_1_API set2403TextArg 1 +attr WR_1_API set2403URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2404Data [{"moduleid":"devices:local","settings":[{"id":"Battery:TimeControl:ConfWed","value":"$val"}]}] +attr WR_1_API set2404FollowGet 24_Battery_TimeControl +attr WR_1_API set2404Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2404Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2404Hint 0,1,2,Battery_TimeControl_3_Mi +attr WR_1_API set2404IExpr my $x = ReadingsVal($name,$val,"null");; $x=~s/\s//gs;; ($val =~ /^-?\d+$/)? $val x96 : ($x =~ /^-?\d+$/)? $x : 0 x96 +attr WR_1_API set2404Method PUT +attr WR_1_API set2404Name 24__3_Battery_TimeControl_Mi +attr WR_1_API set2404TextArg 1 +attr WR_1_API set2404URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2405Data [{"moduleid":"devices:local","settings":[{"id":"Battery:TimeControl:ConfThu","value":"$val"}]}] +attr WR_1_API set2405FollowGet 24_Battery_TimeControl +attr WR_1_API set2405Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2405Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2405Hint 0,1,2,Battery_TimeControl_4_Do +attr WR_1_API set2405IExpr my $x = ReadingsVal($name,$val,"null");; $x=~s/\s//gs;; ($val =~ /^-?\d+$/)? $val x96 : ($x =~ /^-?\d+$/)? $x : 0 x96 +attr WR_1_API set2405Method PUT +attr WR_1_API set2405Name 24__4_Battery_TimeControl_Do +attr WR_1_API set2405URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2406Data [{"moduleid":"devices:local","settings":[{"id":"Battery:TimeControl:ConfFri","value":"$val"}]}] +attr WR_1_API set2406FollowGet 24_Battery_TimeControl +attr WR_1_API set2406Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2406Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2406Hint 0,1,2,Battery_TimeControl_5_Fr +attr WR_1_API set2406IExpr my $x = ReadingsVal($name,$val,"null");; $x=~s/\s//gs;; ($val =~ /^-?\d+$/)? $val x96 : ($x =~ /^-?\d+$/)? $x : 0 x96 +attr WR_1_API set2406Method PUT +attr WR_1_API set2406Name 24__5_Battery_TimeControl_Fr +attr WR_1_API set2406URL http://%IP-WR%/api/v1/settings +attr WR_1_API set2407Data [{"moduleid":"devices:local","settings":[{"id":"Battery:TimeControl:ConfSat","value":"$val"}]}] +attr WR_1_API set2407Header01 authorization: Session %auth_sessionId% +attr WR_1_API set2407Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set2407Hint 0,1,2,Battery_TimeControl_6_Sa +attr WR_1_API set2407IExpr my $x = ReadingsVal($name,$val,"null");; $x=~s/\s//gs;; ($val =~ /^-?\d+$/)? $val x96 : ($x =~ /^-?\d+$/)? $x : 0 x96 +attr WR_1_API set2407Method PUT +attr WR_1_API set2407Name 24__6_Battery_TimeControl_Sa +attr WR_1_API set2407URL http://%IP-WR%/api/v1/settings +attr WR_1_API set4002Data [{"moduleid":"devices:local","settings":[{"id":"Generator:ShadowMgmt:Enable","value":"$val"}]}] +attr WR_1_API set4002FollowGet 40_Generator_und_EnergieMgmt +attr WR_1_API set4002Header01 authorization: Session %auth_sessionId% +attr WR_1_API set4002Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set4002Hint slider,0,1,3 +attr WR_1_API set4002Method PUT +attr WR_1_API set4002Name 40_02_Generator_ShadowMgmt +attr WR_1_API set4002URL http://%IP-WR%/api/v1/settings +attr WR_1_API set4101Data [{"moduleid":"devices:local","settings":[{"id":"DigitalOutputs:Customer:ConfigurationFlags","value":"$val"},{"id":"DigitalOutputs:Customer:DelayTime","value":"5"},{"id":"DigitalOutputs:Customer:PowerMode:OnPowerThreshold","value":"100000"},{"id":"DigitalOutputs:Customer:TimeMode:MaxNoOfSwitchingCyclesPerDay","value":"24"},{"id":"DigitalOutputs:Customer:TimeMode:PowerThreshold","value":"1"},{"id":"DigitalOutputs:Customer:TimeMode:RunTime","value":"1440"},{"id":"DigitalOutputs:Customer:TimeMode:StableTime","value":"1"}]}] +attr WR_1_API set4101FollowGet 41_DigitalOutputs +attr WR_1_API set4101Header01 authorization: Session %auth_sessionId% +attr WR_1_API set4101Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set4101Hint 0,9,13,14 +attr WR_1_API set4101Method PUT +attr WR_1_API set4101Name 41_01_DigitalOutputs +attr WR_1_API set4101URL http://%IP-WR%/api/v1/settings +attr WR_1_API set50-10Name Event_02_code +attr WR_1_API set50-11Name Event_02_description +attr WR_1_API set50-12Name Event_02_end_time +attr WR_1_API set50-13Name Event_02_group +attr WR_1_API set50-14Name Event_02_is_active +attr WR_1_API set50-15Name Event_02_long_description +attr WR_1_API set50-16Name Event_02_start_time +attr WR_1_API set50-17Name Event_03_category +attr WR_1_API set50-18Name Event_03_code +attr WR_1_API set50-19Name Event_03_description +attr WR_1_API set50-1Name Event_01_category +attr WR_1_API set50-20Name Event_03_end_time +attr WR_1_API set50-21Name Event_03_group +attr WR_1_API set50-22Name Event_03_is_active +attr WR_1_API set50-23Name Event_03_long_description +attr WR_1_API set50-24Name Event_03_start_time +attr WR_1_API set50-25Name Event_04_category +attr WR_1_API set50-26Name Event_04_code +attr WR_1_API set50-27Name Event_04_description +attr WR_1_API set50-28Name Event_04_end_time +attr WR_1_API set50-29Name Event_04_group +attr WR_1_API set50-2Name Event_01_code +attr WR_1_API set50-30Name Event_04_is_active +attr WR_1_API set50-31Name Event_04_long_description +attr WR_1_API set50-32Name Event_04_start_time +attr WR_1_API set50-33Name Event_05_category +attr WR_1_API set50-34Name Event_05_code +attr WR_1_API set50-35Name Event_05_description +attr WR_1_API set50-36Name Event_05_end_time +attr WR_1_API set50-37Name Event_05_group +attr WR_1_API set50-38Name Event_05_is_active +attr WR_1_API set50-39Name Event_05_long_description +attr WR_1_API set50-3Name Event_01_description +attr WR_1_API set50-40Name Event_05_start_time +attr WR_1_API set50-4Name Event_01_end_time +attr WR_1_API set50-5Name Event_01_group +attr WR_1_API set50-6Name Event_01_is_active +attr WR_1_API set50-7Name Event_01_long_description +attr WR_1_API set50-8Name Event_01_start_time +attr WR_1_API set50-9Name Event_02_category +attr WR_1_API set50Data {"max":5,"language":"$val"} +attr WR_1_API set50Header01 authorization: Session %auth_sessionId% +attr WR_1_API set50Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set50Hint en-gb,de-de +attr WR_1_API set50JSON . +attr WR_1_API set50Name 50_events_latest_5 +attr WR_1_API set50ParseResponse 1 +attr WR_1_API set50TextArg 1 +attr WR_1_API set50URL http://%IP-WR%/api/v1/events/latest +attr WR_1_API set6001Header01 authorization: Session %auth_sessionId% +attr WR_1_API set6001Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_1_API set6001Method POST +attr WR_1_API set6001Name 60_01_Reset_Wechselrichter +attr WR_1_API set6001NoArg 1 +attr WR_1_API set6001URL http://%IP-WR%/api/v1/system/reboot +attr WR_1_API showBody 1 +attr WR_1_API showError 1 +attr WR_1_API sid01Data %START% +attr WR_1_API sid01ParseResponse 1 +attr WR_1_API sid01URL http://%IP-WR%/api/v1/auth/start +attr WR_1_API sid02Data %FINISH% +attr WR_1_API sid02ParseResponse 1 +attr WR_1_API sid02URL http://%IP-WR%/api/v1/auth/finish +attr WR_1_API sid03Data %SESSION% +attr WR_1_API sid03ParseResponse 1 +attr WR_1_API sid03URL http://%IP-WR%/api/v1/auth/create_session +attr WR_1_API sidHeader01 Accept-Encoding: gzip,deflate +attr WR_1_API sidHeader02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_1_API sortby 112 +attr WR_1_API stateFormat {\ +if (AttrVal("$name","verbose",0) >=3) {\ + my $calcVal = 0;;\ + my $WR = "WR_1";;\ + my $YearBefore = "LogDBRep_Statistic_previous_Year";;\ + my $YearPrevious = ReadingsTimestamp("$YearBefore","SW_Statistic_Yield_Year","null");;\ + $YearPrevious = ($YearPrevious ne "null") ? POSIX::strftime("%Y",localtime(time_str2num(ReadingsTimestamp("$YearBefore","SW_Statistic_Yield_Year","null")))) : "null";;\ +\ + my $QuarterBefore = "LogDBRep_Statistic_previous_Quarter";;\ + my $QuarterPrevious = "null";;\ + foreach my $i (1,2,3,4) {if (ReadingsVal("$QuarterBefore","Q".$i,0) eq "previous"){ $QuarterPrevious = "Q".$i }};;\ +\ + my $pvt = sprintf("%04d W",ReadingsVal($WR,"SW_Total_AC_Active_P",0) );;\ + my $pvtd = sprintf("%04d",ReadingsVal("$name","SW_Statistic_Yield_Day",0)/1000 );;\ + my $pvtm = sprintf("%04d",ReadingsVal("$name","SW_Statistic_Yield_Month",0)/1000 );;\ + $pvtm .= ($QuarterPrevious ne "null") ? sprintf(" / %04d", ReadingsVal("$QuarterBefore",$QuarterPrevious."_SW_Statistic_Yield",0) ) : "";;\ + my $pvty = sprintf("%05d",ReadingsVal("$name","SW_Statistic_Yield_Year",0)/1000 );;\ + $pvty .= ($YearPrevious ne "null") ? sprintf(" / %05d", ReadingsVal("$YearBefore","SW_Statistic_Yield_Year",0) ) : "";;\ +\ + my $pv = sprintf("%04d W",ReadingsVal($WR,"SW_Home_own_consumption_from_Battery",0)+ReadingsVal($WR,"SW_Home_own_consumption_from_PV",0) );;\ + my $pvd = sprintf("%04d",ReadingsVal("$name","SW_Statistic_EnergyHomePv_Day",0)/1000 );;\ + my $pvm = sprintf("%04d",ReadingsVal("$name","SW_Statistic_EnergyHomePv_Month",0)/1000 );;\ + $pvm .= ($QuarterPrevious ne "null") ? sprintf(" / %04d", ReadingsVal("$QuarterBefore",$QuarterPrevious."_SW_Statistic_EnergyHomePv",0) ) : "";;\ + my $pvy = sprintf("%05d",ReadingsVal("$name","SW_Statistic_EnergyHomePv_Year",0)/1000 );;\ + $pvy .= ($YearPrevious ne "null") ? sprintf(" / %05d", ReadingsVal("$YearBefore","SW_Statistic_EnergyHomePv_Year",0) ) : "";;\ + \ + my $gfi = sprintf("%04d W",(ReadingsVal($WR,"Total_Active_P_EM",0)<=0 ? abs(round(ReadingsVal($WR,"Total_Active_P_EM",0),0)): 0) );;\ + my $gfid = sprintf("%04d",ReadingsVal("$name","SW_Statistic_EnergyHomeFeedInGrid_Day",0)/1000 );;\ + my $gfim = sprintf("%04d",ReadingsVal("$name","SW_Statistic_EnergyHomeFeedInGrid_Month",0)/1000 );;\ + $gfim .= ($QuarterPrevious ne "null") ? sprintf(" / %04d", ReadingsVal("$QuarterBefore",$QuarterPrevious."_SW_Statistic_EnergyHomeFeedInGrid",0) ) : "";;\ + my $gfiy = sprintf("%05d",ReadingsVal("$name","SW_Statistic_EnergyHomeFeedInGrid_Year",0)/1000 );;\ + $gfiy .= ($YearPrevious ne "null") ? sprintf(" / %05d", ReadingsVal("$YearBefore","SW_Statistic_EnergyHomeFeedInGrid_Year",0) ) : "";;\ + \ + my $eb = sprintf("%04d W",(ReadingsVal($WR,"Total_Active_P_EM",0)>=0 ? round(ReadingsVal($WR,"Total_Active_P_EM",0),0) : 0) );;\ + my $ebd = sprintf("%04d",ReadingsVal("$name","SW_Statistic_EnergyHomeGrid_Day",0)/1000 );;\ + my $ebm = sprintf("%04d",ReadingsVal("$name","SW_Statistic_EnergyHomeGrid_Month",0)/1000 );;\ + $ebm .= ($QuarterPrevious ne "null") ? sprintf(" / %04d", ReadingsVal("$QuarterBefore",$QuarterPrevious."_SW_Statistic_EnergyHomeGrid",0) ) : "";;\ + my $eby = sprintf("%05d",ReadingsVal("$name","SW_Statistic_EnergyHomeGrid_Year",0)/1000 );;\ + $eby .= ($YearPrevious ne "null") ? sprintf(" / %05d", ReadingsVal("$YearBefore","SW_Statistic_EnergyHomeGrid_Year",0) ) : "";;\ +\ + my $pvb = sprintf("%04d W",ReadingsVal($WR,"SW_Home_own_consumption_from_Battery",0));;\ + my $pvbd = sprintf("%04d",ReadingsVal("$name","Statistic_EnergyHomeBat_Day",0)/1000 );;\ + my $pvbm = sprintf("%04d",ReadingsVal("$name","Statistic_EnergyHomeBat_Month",0)/1000 );;\ + $pvbm .= ($QuarterPrevious ne "null") ? sprintf(" / %04d", ReadingsVal("$QuarterBefore",$QuarterPrevious."_Statistic_EnergyHomeBat",0) ) : "";;\ + my $pvby = sprintf("%05d",ReadingsVal("$name","Statistic_EnergyHomeBat_Year",0)/1000 );;\ + $pvby .= ($YearPrevious ne "null") ? sprintf(" / %05d", ReadingsVal("$YearBefore","Statistic_EnergyHomeBat_Year",0) ) : "";;\ +\ + my $et = sprintf("%04d W",(ReadingsVal($WR,"SW_Home_own_consumption_from_PV",0)+ReadingsVal($WR,"SW_Home_own_consumption_from_Battery",0)+ReadingsVal($WR,"SW_Home_own_consumption_from_grid",0)) );;\ + my $etd = sprintf("%04d",ReadingsVal("$name","SW_Statistic_TotalConsumption_Day",0)/1000 );;\ + my $etm = sprintf("%04d",ReadingsVal("$name","SW_Statistic_TotalConsumption_Month",0)/1000 );;\ + $etm .= ($QuarterPrevious ne "null") ? sprintf(" / %04d", ReadingsVal("$QuarterBefore",$QuarterPrevious."_SW_Statistic_TotalConsumption",0) ) : "";;\ + my $ety = sprintf("%05d",ReadingsVal("$name","SW_Statistic_TotalConsumption_Year",0)/1000 );;\ + $ety .= ($YearPrevious ne "null") ? sprintf(" / %05d", ReadingsVal("$YearBefore","SW_Statistic_TotalConsumption_Year",0) ) : "";;\ +\ + my $valA = ReadingsVal($WR, "SW_Total_AC_Active_P",0)-ReadingsVal($WR, "SW_Home_own_consumption_from_grid",0);;\ + $calcVal = ($valA > 0) ? round($valA /($valA + ReadingsVal($WR, "SW_Home_own_consumption_from_grid",""))*100 ,0) : 0;;\ + my $aq = sprintf("%4d %%",(($calcVal > 100) ? 100 : $calcVal) );;\ + \ + my $aqd = sprintf("%3d %%",ReadingsVal("$name","SW_Statistic_Autarky_Day",0) );;\ + my $aqm = sprintf("%3d %%",ReadingsVal("$name","SW_Statistic_Autarky_Month",0) );;\ + my $aqy = sprintf("%3d %%",ReadingsVal("$name","SW_Statistic_Autarky_Year",0) );;\ + $aqy .= ($YearPrevious ne "null") ? sprintf(" / %3d %%", ReadingsVal("$YearBefore","SW_Statistic_Autarky_Year",0) ) : "";;\ + \ + my $valS = ReadingsVal($WR,"SW_Total_AC_Active_P",0);;\ + $calcVal = ($valS > 0) ? round((ReadingsVal($WR,"SW_Home_own_consumption_from_PV",0) + ReadingsVal($WR,"SW_Home_own_consumption_from_Battery",0)) / $valS * 100 ,0) : 0;;\ + my $sq = sprintf("%4d %%",(($calcVal > 100) ? 100 : $calcVal) );;\ +\ + my $sqd = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_OwnConsumptionRate_Day",0) );;\ + my $sqm = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_OwnConsumptionRate_Month",0) );;\ + my $sqy = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_OwnConsumptionRate_Year",0) );;\ + $sqy .= ($YearPrevious ne "null") ? sprintf(" / %3d %%", ReadingsVal("$YearBefore","SW_Statistic_OwnConsumptionRate_Year",0) ) : "";;\ + \ + my $date = POSIX::strftime("%Y-%m-%d",localtime(time_str2num(ReadingsTimestamp($name, "auth_me_authenticated",0))));;\ + my $md = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "auth_me_authenticated",0))));;\ + my $cd = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SW_Statistic_Autarky_Day",0))));;\ + my $cm = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SW_Statistic_Autarky_Month",0))));;\ + $cm .= ($QuarterPrevious ne "null") ? " / ".POSIX::strftime("%d.%m",localtime(time_str2num(ReadingsTimestamp("$QuarterBefore","$QuarterPrevious",0) ))) : "";;\ + my $cy = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SW_Statistic_Autarky_Year",0))));;\ + $cy .= ($YearPrevious ne "null") ? " / ".$YearPrevious : "";;\ +\ +"\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
Statistik vom $date in kWhaktuellHeuteMonat".(($QuarterPrevious ne "null") ? " / ".$QuarterPrevious : "")."Jahr".(($YearPrevious ne "0") ? " / Vorjahr" : "")."
Erzeugung PV-Total".$pvt."".$pvtd."".$pvtm."".$pvty."
Bezug von PV".$pv."".$pvd."".$pvm."".$pvy."
Bezug von Batterie".$pvb."".$pvbd."".$pvbm."".$pvby."
Bezug ins Haus (Energieverbrauch)".$et."".$etd."".$etm."".$ety."
Bezug vom Netz".$eb."".$ebd."".$ebm."".$eby."
Einspeisung ins Netz".$gfi."".$gfid."".$gfim."".$gfiy."
Autarkiequote".$aq."".$aqd."".$aqm."".$aqy."
Eigenverbrauchsquote".$sq."".$sqd."".$sqm."".$sqy."
Berechnet um".$md."".$cd."".$cm."".$cy."
"\ +}\ +}\ + +attr WR_1_API timeout 7 +attr WR_1_API userReadings Statistic_EnergyHomePvSum_Day:Statistic_EnergyHomePv_Day.* {round( (ReadingsVal("$NAME","Statistic_EnergyHomeBat_Day", "0")+ReadingsVal("$NAME","Statistic_EnergyHomePv_Day", "0")) ,2)},\ +\ +Statistic_EnergyHomePvSum_Month:Statistic_EnergyHomePv_Month.* {round( (ReadingsVal("$NAME","Statistic_EnergyHomeBat_Month", "0")+ReadingsVal("$NAME","Statistic_EnergyHomePv_Month", "0")) ,2)},\ +\ +Statistic_EnergyHomePvSum_Year:Statistic_EnergyHomePv_Year.* {round( (ReadingsVal("$NAME","Statistic_EnergyHomeBat_Year", "0")+ReadingsVal("$NAME","Statistic_EnergyHomePv_Year", "0")) ,2)},\ +\ +\ +Statistic_EnergyFeedInGrid_Day:Statistic_Yield_Day.* {round((ReadingsVal("$NAME","Statistic_Yield_Day", "")-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Day", "0")-ReadingsVal("$NAME","Statistic_EnergyHomePv_Day", "0")),2)},\ +\ +Statistic_EnergyFeedInGrid_Month:Statistic_Yield_Month.* {round((ReadingsVal("$NAME","Statistic_Yield_Month", "")-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Month", "0")-ReadingsVal("$NAME","Statistic_EnergyHomePv_Month", "0")),2)},\ +\ +Statistic_EnergyFeedInGrid_Year:Statistic_Yield_Year.* {round((ReadingsVal("$NAME","Statistic_Yield_Year", "")-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Year", "0")-ReadingsVal("$NAME","Statistic_EnergyHomePv_Year", "0")),2)},\ +\ +\ +Statistic_TotalConsumption_Day:Statistic_EnergyHomePv_Day.* { round((ReadingsVal("$NAME","Statistic_EnergyHomePv_Day","0")+ReadingsVal("$NAME","Statistic_EnergyHomeBat_Day","0")+ReadingsVal("$NAME","Statistic_EnergyHomeGrid_Day","0") ) ,2) },\ +\ +Statistic_TotalConsumption_Month:Statistic_EnergyHomePv_Month.* { round((ReadingsVal("$NAME","Statistic_EnergyHomePv_Month","0")+ReadingsVal("$NAME","Statistic_EnergyHomeBat_Month","0")+ReadingsVal("$NAME","Statistic_EnergyHomeGrid_Month","0") ) ,2) },\ +\ +Statistic_TotalConsumption_Year:Statistic_EnergyHomePv_Year.* { round( (ReadingsVal("$NAME","Statistic_EnergyHomePv_Year","0")+ReadingsVal("$NAME","Statistic_EnergyHomeBat_Year","0")+ReadingsVal("$NAME","Statistic_EnergyHomeGrid_Year","0") ),2) },\ +\ +\ +Statistic_Yield_NoBat_Day:Statistic_Yield_Day.* { round((ReadingsVal("$NAME","Statistic_Yield_Day",0)-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Day",0)),0) },\ +Statistic_Yield_NoBat_Month:Statistic_Yield_Month.* { round((ReadingsVal("$NAME","Statistic_Yield_Month",0)-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Month",0)),0) },\ +Statistic_Yield_NoBat_Year:Statistic_Yield_Year.* { round((ReadingsVal("$NAME","Statistic_Yield_Year",0)-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Year",0)),0) },\ +\ +\ +SW_Statistic_EnergyPv1_Day:Statistic_EnergyPv1_Day.* { round(ReadingsVal("$NAME","Statistic_EnergyPv1_Day",0),0)},\ +SW_Statistic_EnergyPv1_Month:Statistic_EnergyPv1_Month.* { round(ReadingsVal("$NAME","Statistic_EnergyPv1_Month",0),0)},\ +SW_Statistic_EnergyPv1_Total:Statistic_EnergyPv1_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyPv1_Total",0),0)},\ +SW_Statistic_EnergyPv1_Year:Statistic_EnergyPv1_Year.* { round(ReadingsVal("$NAME","Statistic_EnergyPv1_Year",0),0)},\ +SW_Statistic_EnergyPv2_Day:Statistic_EnergyPv2_Day.* { round(ReadingsVal("$NAME","Statistic_EnergyPv2_Day",0),0)},\ +SW_Statistic_EnergyPv2_Month:Statistic_EnergyPv2_Month.* { round(ReadingsVal("$NAME","Statistic_EnergyPv2_Month",0),0)},\ +SW_Statistic_EnergyPv2_Total:Statistic_EnergyPv2_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyPv2_Total",0),0)},\ +SW_Statistic_EnergyPv2_Year:Statistic_EnergyPv2_Year.* { round(ReadingsVal("$NAME","Statistic_EnergyPv2_Year",0),0)},\ +SW_Statistic_EnergyPv3_Day:Statistic_EnergyPv3_Day.* { round(ReadingsVal("$NAME","Statistic_EnergyPv3_Day",0),0)},\ +SW_Statistic_EnergyPv3_Month:Statistic_EnergyPv3_Month.* { round(ReadingsVal("$NAME","Statistic_EnergyPv3_Month",0),0)},\ +SW_Statistic_EnergyPv3_Total:Statistic_EnergyPv3_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyPv3_Total",0),0)},\ +SW_Statistic_EnergyPv3_Year:Statistic_EnergyPv3_Year.* { round(ReadingsVal("$NAME","Statistic_EnergyPv3_Year",0),0)},\ +\ +SW_Statistic_EnergyPv4_Day:Statistic_EnergyPv1_Day.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv1_Day",0),0)},\ +SW_Statistic_EnergyPv4_Month:Statistic_EnergyPv1_Month.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv1_Month",0),0)},\ +SW_Statistic_EnergyPv4_Total:Statistic_EnergyPv1_Total.* monotonic { round(ReadingsVal("WR_2_API","Statistic_EnergyPv1_Total",0),0)},\ +SW_Statistic_EnergyPv4_Year:Statistic_EnergyPv1_Year.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv1_Year",0),0)},\ +SW_Statistic_EnergyPv5_Day:Statistic_EnergyPv2_Day.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv2_Day",0),0)},\ +SW_Statistic_EnergyPv5_Month:Statistic_EnergyPv2_Month.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv2_Month",0),0)},\ +SW_Statistic_EnergyPv5_Total:Statistic_EnergyPv2_Total.* monotonic { round(ReadingsVal("WR_2_API","Statistic_EnergyPv2_Total",0),0)},\ +SW_Statistic_EnergyPv5_Year:Statistic_EnergyPv2_Year.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv2_Year",0),0)},\ +SW_Statistic_EnergyPv6_Day:Statistic_EnergyPv3_Day.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv3_Day",0),0)},\ +SW_Statistic_EnergyPv6_Month:Statistic_EnergyPv3_Month.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv3_Month",0),0)},\ +SW_Statistic_EnergyPv6_Total:Statistic_EnergyPv3_Total.* monotonic { round(ReadingsVal("WR_2_API","Statistic_EnergyPv3_Total",0),0)},\ +SW_Statistic_EnergyPv6_Year:Statistic_EnergyPv3_Year.* { round(ReadingsVal("WR_2_API","Statistic_EnergyPv3_Year",0),0)},\ +\ +SW_Statistic_Yield_Day:Statistic_Yield_Day.* { round(ReadingsVal("$NAME","Statistic_Yield_Day",0)+ReadingsVal("WR_2_API","Statistic_Yield_Day",0),0)},\ +SW_Statistic_Yield_Month:Statistic_Yield_Month.* { round(ReadingsVal("$NAME","Statistic_Yield_Month",0)+ReadingsVal("WR_2_API","Statistic_Yield_Month",0),0)},\ +SW_Statistic_Yield_Total:Statistic_Yield_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_Yield_Total",0)+ReadingsVal("WR_2_API","Statistic_Yield_Total",0),0)},\ +SW_Statistic_Yield_Year:Statistic_Yield_Year.* { round(ReadingsVal("$NAME","Statistic_Yield_Year",0)+ReadingsVal("WR_2_API","Statistic_Yield_Year",0),0)},\ +\ +SW_Statistic_Yield_NoBat_Day:Statistic_Yield_Day.* { round((ReadingsVal("$NAME","SW_Statistic_Yield_Day",0)-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Day",0)),0)},\ +SW_Statistic_Yield_NoBat_Month:Statistic_Yield_Month.* { round((ReadingsVal("$NAME","SW_Statistic_Yield_Month",0)-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Month",0)),0)},\ +SW_Statistic_Yield_NoBat_Year:Statistic_Yield_Year.* { round((ReadingsVal("$NAME","SW_Statistic_Yield_Year",0)-ReadingsVal("$NAME","Statistic_EnergyHomeBat_Year",0)),0)},\ +\ +SW_Statistic_EnergyHomeFeedInGrid_Day:SW_Statistic_Yield_Day.* { (ReadingsVal("WR_0_KSEM","Active_energy-",0) - ReadingsVal("$NAME","SW_Meter_init_FeedInGrid_Day",0)) * 1000 },\ +SW_Statistic_EnergyHomeFeedInGrid_Month:SW_Statistic_Yield_Month.* { (ReadingsVal("WR_0_KSEM","Active_energy-",0) - ReadingsVal("$NAME","SW_Meter_init_FeedInGrid_Month",0)) * 1000 },\ +SW_Statistic_EnergyHomeFeedInGrid_Year:SW_Statistic_Yield_Year.* { (ReadingsVal("WR_0_KSEM","Active_energy-",0) - ReadingsVal("$NAME","SW_Meter_init_FeedInGrid_Year",0)) * 1000 },\ +\ +SW_Statistic_EnergyHomeGrid_Day:SW_Statistic_Yield_Day.* { (ReadingsVal("WR_0_KSEM","Active_energy+",0) - ReadingsVal("$NAME","SW_Meter_init_Grid_Day",0)) * 1000 },\ +SW_Statistic_EnergyHomeGrid_Month:SW_Statistic_Yield_Month.* { (ReadingsVal("WR_0_KSEM","Active_energy+",0) - ReadingsVal("$NAME","SW_Meter_init_Grid_Month",0)) * 1000 },\ +SW_Statistic_EnergyHomeGrid_Year:SW_Statistic_Yield_Year.* { (ReadingsVal("WR_0_KSEM","Active_energy+",0) - ReadingsVal("$NAME","SW_Meter_init_Grid_Year",0)) * 1000 },\ +\ +SW_Statistic_EnergyHomePv_Day:SW_Statistic_EnergyHomeFeedInGrid_Day.* { round(ReadingsVal("$NAME","SW_Statistic_Yield_Day",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Day",0) - ReadingsVal("$NAME","Statistic_EnergyHomeBat_Day",0),0) },\ +SW_Statistic_EnergyHomePv_Month:SW_Statistic_EnergyHomeFeedInGrid_Month.* { round(ReadingsVal("$NAME","SW_Statistic_Yield_Month",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Month",0) - ReadingsVal("$NAME","Statistic_EnergyHomeBat_Month",0),0) },\ +SW_Statistic_EnergyHomePv_Year:SW_Statistic_EnergyHomeFeedInGrid_Year.* { round(ReadingsVal("$NAME","SW_Statistic_Yield_Year",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Year",0) - ReadingsVal("$NAME","Statistic_EnergyHomeBat_Year",0),0) },\ +\ +SW_Statistic_EnergyHomePvSum_Day:SW_Statistic_EnergyHomeFeedInGrid_Day.* { round(ReadingsVal("$NAME","SW_Statistic_Yield_Day",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Day",0),0) },\ +SW_Statistic_EnergyHomePvSum_Month:SW_Statistic_EnergyHomeFeedInGrid_Month.* { round(ReadingsVal("$NAME","SW_Statistic_Yield_Month",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Month",0),0) },\ +SW_Statistic_EnergyHomePvSum_Year:SW_Statistic_EnergyHomeFeedInGrid_Year.* { round(ReadingsVal("$NAME","SW_Statistic_Yield_Year",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Year",0),0) },\ +\ +SW_Statistic_EnergyHome_Day:SW_Statistic_EnergyHomeFeedInGrid_Day.* { ReadingsVal("$NAME","SW_Statistic_Yield_Day",0) + ReadingsVal("$NAME","SW_Statistic_EnergyHomeGrid_Day",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Day" ,0) },\ +SW_Statistic_EnergyHome_Month:SW_Statistic_EnergyHomeFeedInGrid_Month.* { ReadingsVal("$NAME","SW_Statistic_Yield_Month",0) + ReadingsVal("$NAME","SW_Statistic_EnergyHomeGrid_Month",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Month",0) },\ +SW_Statistic_EnergyHome_Year:SW_Statistic_EnergyHomeFeedInGrid_Year.* { ReadingsVal("$NAME","SW_Statistic_Yield_Year",0) + ReadingsVal("$NAME","SW_Statistic_EnergyHomeGrid_Year",0) - ReadingsVal("$NAME","SW_Statistic_EnergyHomeFeedInGrid_Year",0) },\ +\ +SW_Statistic_TotalConsumption_Day:SW_Statistic_EnergyHomePv_Day.* { round( (ReadingsVal("$NAME","SW_Statistic_EnergyHomePv_Day",0)+ReadingsVal("$NAME","Statistic_EnergyHomeBat_Day",0)+ReadingsVal("$NAME","SW_Statistic_EnergyHomeGrid_Day",0) ) ,0) },\ +SW_Statistic_TotalConsumption_Month:SW_Statistic_EnergyHomePv_Month.* { round( (ReadingsVal("$NAME","SW_Statistic_EnergyHomePv_Month",0)+ReadingsVal("$NAME","Statistic_EnergyHomeBat_Month",0) +ReadingsVal("$NAME","SW_Statistic_EnergyHomeGrid_Month",0) ),0) },\ +SW_Statistic_TotalConsumption_Year:SW_Statistic_EnergyHomePv_Year.* { round( (ReadingsVal("$NAME","SW_Statistic_EnergyHomePv_Year",0)+ReadingsVal("$NAME","Statistic_EnergyHomeBat_Year",0) +ReadingsVal("$NAME","SW_Statistic_EnergyHomeGrid_Year",0) ),0) },\ +\ +SW_Statistic_Autarky_Day:SW_Statistic_EnergyHomePvSum_Day.* { my $SW_Statistic_EnergyHome_Day = ReadingsVal("$NAME","SW_Statistic_EnergyHome_Day",0) ;;;; ($SW_Statistic_EnergyHome_Day eq 0)? 0 : round(ReadingsVal("$NAME","SW_Statistic_EnergyHomePvSum_Day",0) / $SW_Statistic_EnergyHome_Day *100,0) },\ +\ +SW_Statistic_Autarky_Month:SW_Statistic_EnergyHomePvSum_Month.* { round(ReadingsVal("$NAME","SW_Statistic_EnergyHomePvSum_Month",0) / ReadingsVal("$NAME","SW_Statistic_EnergyHome_Month",0) *100,0) },\ +SW_Statistic_Autarky_Year:SW_Statistic_EnergyHomePvSum_Year.* { round(ReadingsVal("$NAME","SW_Statistic_EnergyHomePvSum_Year",0) / ReadingsVal("$NAME","SW_Statistic_EnergyHome_Year",0) *100,0) },\ +\ +SW_Statistic_OwnConsumptionRate_Day:SW_Statistic_EnergyHomePvSum_Day.* {my $SW_Statistic_Yield_Day = ReadingsVal("$NAME","SW_Statistic_Yield_Day",0) ;;;; ($SW_Statistic_Yield_Day eq 0)? 0 : round(ReadingsVal("$NAME","SW_Statistic_EnergyHomePvSum_Day" ,0) / $SW_Statistic_Yield_Day*100,0) },\ +SW_Statistic_OwnConsumptionRate_Month:SW_Statistic_EnergyHomePvSum_Month.* {my $SW_Statistic_Yield_Month = ReadingsVal("$NAME","SW_Statistic_Yield_Month",0) ;;;; ($SW_Statistic_Yield_Month eq 0)? 0 : round(ReadingsVal("$NAME","SW_Statistic_EnergyHomePvSum_Month" ,0) / $SW_Statistic_Yield_Month*100,0) },\ +SW_Statistic_OwnConsumptionRate_Year:SW_Statistic_EnergyHomePvSum_Year.* {my $SW_Statistic_Yield_Year = ReadingsVal("$NAME","SW_Statistic_Yield_Year",0) ;;;; ($SW_Statistic_Yield_Year eq 0)? 0 : round(ReadingsVal("$NAME","SW_Statistic_EnergyHomePvSum_Year" ,0) / $SW_Statistic_Yield_Year*100,0) },\ +\ +SW_Statistic_EnergyChargeGrid_Total:Statistic_EnergyChargeGrid_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyChargeGrid_Total",0),0)},\ +SW_Statistic_EnergyChargeInvIn_Total:Statistic_EnergyChargeInvIn_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyChargeInvIn_Total",0),0)},\ +SW_Statistic_EnergyChargePv_Total:Statistic_EnergyChargePv_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyChargePv_Total",0),0)},\ +SW_Statistic_EnergyDischargeGrid_Total:Statistic_EnergyDischargeGrid_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyDischargeGrid_Total",0),0)},\ +SW_Statistic_EnergyDischarge_Total:Statistic_EnergyDischarge_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyDischarge_Total",0),0)},\ +SW_Statistic_EnergyHomeBat_Total:Statistic_EnergyHomeBat_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyHomeBat_Total",0),0)},\ +SW_Statistic_EnergyHomeGrid_Total:Statistic_EnergyHomeGrid_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyHomeGrid_Total",0),0)},\ +SW_Statistic_EnergyHomeOwn_Total:Statistic_EnergyHomeOwn_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyHomeOwn_Total",0),0)},\ +SW_Statistic_EnergyHomePv_Total:Statistic_EnergyHomePv_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyHomePv_Total",0),0)},\ +SW_Statistic_EnergyHome_Total:Statistic_EnergyHome_Total.* monotonic { round(ReadingsVal("$NAME","Statistic_EnergyHome_Total",0),0)},\ +\ +SW_Statistic_Autarky_Total:SW_Statistic_EnergyHomePv_Total.* { round(ReadingsVal("$NAME","SW_Statistic_EnergyHomePv_Total",0) / ReadingsVal("$NAME","SW_Statistic_EnergyHome_Total",0) *100,0) },\ +\ +SW_Statistic_OwnConsumptionRate_Total:SW_Statistic_EnergyHomePv_Total.* {my $SW_Statistic_Yield_Total = ReadingsVal("$NAME","SW_Statistic_Yield_Total",0) ;;;; ($SW_Statistic_Yield_Total eq 0)? 0 : round(ReadingsVal("$NAME","SW_Statistic_EnergyHomePv_Total" ,0) / $SW_Statistic_Yield_Total*100,0) } +attr WR_1_API verbose 0 \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1_Speicher_1_ExternControl.txt b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1_Speicher_1_ExternControl.txt new file mode 100644 index 000000000..b9ecbf141 --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_1_Speicher_1_ExternControl.txt @@ -0,0 +1,985 @@ +defmod WR_1_Speicher_1_ExternControl DOIF ################################################################################################################\ +## 1 Speicher Status vom WR_1_Speicher_1 aktualisieren.\ +## Dies geschieht über das WR_1_API Device, da der Speicher direkt am Wechselrichter angeschlossen ist.\ +##\ +1_Status_WR_1_Speicher_1\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ( [:52] ## jede Stunde\ +\ + or [$SELF:ui_command_1] eq "Status_Speicher" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "Status_Speicher" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ +\ + ::CommandGet(undef, "WR_1_API 21_Battery_Information");;\ + ::CommandGet(undef, "WR_1_API 22_Battery_InternControl");;\ + ::CommandGet(undef, "WR_1_API 23_Battery_ExternControl");;\ + ::CommandGet(undef, "WR_1_API 25_Battery_EM_State");;\ + + if (AttrVal("$SELF","verbose",0) >=4) {\ + Log 3, "$SELF cmd_1 : Speicher Status abfrage"\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 2 Wenn die Ladung im Herbst/Winter unter MinSoc geht allen PV Überschuss in die Batterie laden\ +##\ +## Im Winter kann der MinSoc, durch den WR Eigenverbrauch, unterschritten werden, deshalb wird vorher auf\ +## smarte_laden umgeschaltet, bis die Batterie wieder einen hohen Soc erreicht hat. Siehe cmd_3 laden_beendet\ +##\ +2_smart_Laden_start_Automatik\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ( [WR_ctl:Yield_fc0_day] < [$SELF:SpeicherMinSOC_fc1_Limit] ## Im Herbst/Winter ist wenig zu erwarten\ + and [WR_1:Act_state_of_charge] <= [WR_1_API:Battery_InternControl_MinSoc] ## Achtung der Speicherstand wird zu niedrig\ + and [WR_1_API:Battery_InternControl_MinHomeConsumption] <= 100 ## Der Speicher steht auf Entladen\ + )\ + or [$SELF:ui_command_1] eq "smart_Laden_start" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "smart_Laden_start" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +\ + ::CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 30000");; ## Speicher für Entladung sperren\ + set_Reading("SpeicherExternTrigger","gesperrt");; ## Externe Trigger verriegeln \ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_2.1: smart_laden aktiviert";;\ + Log 3, "$SELF cmd_2.1: SpeicherExternTrigger, Entlademodus gesperrt";;\ + }\ + }\ +}\ +\ +2_smart_Laden_start_WB\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and ( [WB_1:lp_1_ChargeStat] eq "loading" ## Ein Fahrzeug wird gerade geladen\ + or [WB_1:lp_2_ChargeStat] eq "loading" )\ + and [$SELF:SpeicherWB_buffer] eq "Aus" ## Der Speicher darf nicht zum Laden verwendet werden\ + or\ + [$SELF:ui_command_1] eq "smart_Laden_starten_WB" ## Hier wird das uiTable select ausgewertet\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "smart_Laden_starten_WB" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +\ + if( [?$SELF:WB_smart_laden_before] eq "---" ) {\ + if([?$SELF:SpeicherExternTrigger] eq "gesperrt" and\ + [?WR_1_API:Battery_InternControl_MinHomeConsumption] eq "30000" ) {\ + set_Reading("WB_smart_laden_before","aktiv");; ## Externe Trigger verriegeln \ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF cmd_2.2: WallBox smart_laden_before aktiv"};;\ + } else {\ + fhem("setreading $SELF WB_smart_laden_before inaktiv");; ## Den vorherigen Zustand merken\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF cmd_2.2: WallBox smart_laden_before inaktiv"};;\ + }\ + } else {\ + if (AttrVal("$SELF","verbose",0) >= 0)\ + {Log 3, "$SELF cmd_2.2: WallBox es wird gerade geladen"};; ## Der vorherige Zustand war schon bekannt\ + }\ +\ + ::CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 30000");; ## Speicher für Entladung sperren\ + set_Reading("SpeicherExternTrigger","gesperrt");; ## Externe Trigger verriegeln \ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_2.2: smart_laden aktiviert";;\ + Log 3, "$SELF cmd_2.2: SpeicherExternTrigger, Entlademodus gesperrt";;\ + }\ + }\ +}\ +\ +################################################################################################################\ +## 3 Beim erreichen von 90% Soc die Entladung wieder frei geben\ +## \ +3_smart_Laden_beenden_Automatik\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + [$SELF:SpeicherEntladung] eq "Automatik" ## Nur für den Automatik Modus\ + and\ + [$SELF:WB_smart_laden_before] eq "---" ## Es wird gerade kein Fahrzeug geladen\ + and\ + (\ + (\ + [WR_1_API:Battery_InternControl_MinHomeConsumption] > 100 ## Das Speicher Entladen ist geperrt\ + and\ + [WR_1:Act_state_of_charge] >= 80 ## Der Speicher ist bereits 80% voll\ + )\ + or [$SELF:ui_command_1] eq "smart_Laden_beenden" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "smart_Laden_beenden" ) { ## Hier wurde manuell aktiviert\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_3.1: Batterie wird mit ".[?$SELF:SpeicherEntladung]." Steuerung gesteuert";;\ + Log 3, "$SELF cmd_3.1: Batterie auf ".[?WR_1:Act_state_of_charge]." %, Entlademodus freigegeben"};;\ + ::CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 50");;\ + set_Reading("SpeicherExternTrigger","none");; ## den externen Trigger wieder freigeben\ + }\ +}\ +\ +3_smart_Laden_beenden_WB\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + (\ + [WB_1:lp_1_ChargeStat] ne "loading" ## Es wird gerade kein Fahrzeug geladen\ + and\ + [WB_1:lp_2_ChargeStat] ne "loading"\ + and\ + [$SELF:WB_smart_laden_before] eq "inaktiv" ## Vorher war es nicht aktiv\ + )\ + or [$SELF:SpeicherWB_buffer] eq "An" ## Der Speicher darf zum Laden verwendet werden\ + or [$SELF:ui_command_1] eq "smart_Laden_beenden_WB" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "smart_Laden_beenden_WB" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +\ + set_Reading("WB_smart_laden_before","---");; ## den Merker wieder zurück setzen\ +\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_3.2: Wallbox smart_laden beenden";;\ + Log 3, "$SELF cmd_3.2: Batterie wird mit ".[?$SELF:SpeicherEntladung]." Steuerung gesteuert";;\ + Log 3, "$SELF cmd_3.2: Batterie auf ".[?WR_1:Act_state_of_charge]." %, Entlademodus freigegeben"};;\ + ::CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 50");;\ +\ + if ( ( [?WB_1:lp_1_ChargeStat] eq "loading" ## Es wird ein Auto geladen\ + or [?WB_1:lp_2_ChargeStat] eq "loading")\ + and [?$SELF:SpeicherWB_buffer] eq "An") {\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_3.2: MaxSOC Limitierung wegen Wallboxnutzung abgeschaltet";;}\ + }\ +\ + set_Reading("SpeicherExternTrigger","none");; ## den externen Trigger wieder freigeben\ + }\ +}\ +\ +################################################################################################################\ +## 3 Wenn vor dem WB_1 laden das smart_Laden aktiv gewesen ist geht es zurück in den Zustand\ +## \ +3_smart_Laden_umschalten_WB\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + [WB_1:lp_1_ChargeStat] ne "loading" ## Es wird gerade kein Fahrzeug geladen\ + and\ + [WB_1:lp_2_ChargeStat] ne "loading" \ + and\ + [$SELF:WB_smart_laden_before] eq "aktiv" ## Vorher war es nicht aktiv\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "smart_Laden_umschalten_WB" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +\ + set_Reading("WB_smart_laden_before","---");; ## den Merker wieder zurück setzen\ +\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_3.3: Batterie wird mit ".[?$SELF:SpeicherEntladung]." Steuerung gesteuert";;\ + Log 3, "$SELF cmd_3.3: WB_1 laden beendet, reaktivieren des smart_Laden"};;\ + ::CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 30000");;\ + set_Reading("SpeicherExternTrigger","gesperrt");; ## Externe Trigger verriegeln \ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_3.3: smart_laden aktiviert";;\ + Log 3, "$SELF cmd_3.3: SpeicherExternTrigger, Entlademodus gesperrt";;\ + }\ + }\ +}\ +\ +################################################################################################################\ +## 3 Bei Zeitsteuerung und guter Prognose bei 40% wieder frei geben\ +## \ +3_smart_Laden_beenden_Zeit\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and [$SELF:SpeicherEntladung] eq "Zeit" ## Nur für den Zeit Modus\ + and [[$SELF:SpeicherZeitStart]-[$SELF:SpeicherZeitEnde]] ## Zeitfenster aktiv ist\ + and [$SELF:WB_smart_laden_before] eq "---" ## Es wird gerade kein Fahrzeug geladen\ + and\ + (\ + [WR_1_API:Battery_InternControl_MinHomeConsumption] > 100\ + and\ + (\ + [WR_1:Act_state_of_charge] >= 40 ## und einem Stand von Soc 40%\ + and\ + ([WR_ctl:Yield_fc0_day] > [$SELF:SpeicherMinSOC_fc1_Limit] ## wenn es heute oder \ + or [WR_ctl:Yield_fc1_day] > [$SELF:SpeicherMinSOC_fc1_Limit]) ## morgen viel Leistung gibt\ + )\ +\ + or [$SELF:ui_command_1] eq "smart_Laden_beenden_zeit" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "smart_Laden_beenden" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_3.3: Batterie wird mit ".[?$SELF:SpeicherEntladung]." Steuerung gesteuert";;\ + Log 3, "$SELF cmd_3.3: Batterie auf ".[?WR_1:Act_state_of_charge]." %, SpeicherExternTrigger, freigegeben";;\ + Log 3, "$SELF cmd_3.3: Die Leistungsprognose von ".[?$SELF:SpeicherMinSOC_fc1_Limit]." wird überschritten"};;\ + set_Reading("SpeicherExternTrigger","frei");; ## Trigger freigeben\ + set_Reading("SpeicherTrigger","entladen");; ## Signalisiere entladen im stateFormat\ + ::CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 50");; ## Speicher für Entladung freigeben\ +\ + }\ +}\ +\ +################################################################################################################\ +## 4 Freigabe der Batterie mit externem Trigger oder bei Zeitsteuerung\ +## z.B. ([07:00-16:00]\ +4_Trigger\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ( [$SELF:SpeicherExternTrigger] eq "frei" ## Verriegelung, wenn zwangsgeladen werden muss\ + and [WR_1_API:Battery_InternControl_MinHomeConsumption] > 100\ + and\ + ( [$SELF:SpeicherEntladung] eq "Trigger" ## Triggersteuerung\ + and [$SELF:SpeicherTrigger] eq "entladen" ## also Speicherentladung freigeben\ + or \ + [$SELF:SpeicherEntladung] eq "Zeit" ## oder bei Zeitsteuerung wenn das\ + and [[$SELF:SpeicherZeitStart]-[$SELF:SpeicherZeitEnde]] ## Zeitfenster aktiv ist\ + )\ + )\ +\ + or [$SELF:ui_command_1] eq "Trigger" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "Trigger" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ + ::CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 50");; ## Speicher für Entladung freigeben\ + set_Reading("SpeicherTrigger","entladen");; ## Signalisiere entladen im stateFormat\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_4 : SpeicherExternTrigger, Entlademodus freigegeben"};;\ +\ + }\ +}\ +\ +################################################################################################################\ +## 5 Sperren der Batterie mit externem Trigger oder bei Zeitsteuerung\ +## z.B. [16:00-07:00]\ +5_Trigger_sperren\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ( [$SELF:SpeicherExternTrigger] eq "frei" ## Verriegelung, wenn zwangsgeladen werden muss\ + and [WR_1_API:Battery_InternControl_MinHomeConsumption] <= 100\ + and\ + ( [$SELF:SpeicherEntladung] eq "Trigger" ## Triggersteuerung\ + and [$SELF:SpeicherTrigger] eq "entladen" ## also Speicherentladung freigeben\ + or \ + [$SELF:SpeicherEntladung] eq "Zeit" ## oder bei Zeitsteuerung wenn das\ + and [[$SELF:SpeicherZeitEnde]-[$SELF:SpeicherZeitStart]] ## Zeitfenster verlassen wurde\ + )\ + )\ +\ + or [$SELF:ui_command_1] eq "Trigger_sperren" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ + ::CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 30000");;## Speicher für Entladung sperren\ + set_Reading("SpeicherTrigger","gesperrt");; ## Signalisiere gesperrt im stateFormat\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_5 : SpeicherExternTrigger, Entlademodus gesperrt (Tarif oder Trigger)"};;\ + }\ +}\ +\ +################################################################################################################\ +## 6 Wiederhole alle 180s die Kommandos der ExternControl Steuerung\ +##\ +6_Kommando_Wiederholung\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ((\ + [WR_1_API:Battery_Control] > 0 and ## Wenn die ExternControl am WR konfiguriert ist\ + [$SELF:SpeicherCmdRepeatActive] eq "An" and ## Wenn die ExternControl Aktiviert ist\ + [$SELF:SpeicherCmdRepeatRunning] eq "An" and ## Wenn es ExternControl Kommandos zum Senden gibt\ + [ {sunrise_abs("HORIZON=+5.0",0,"6:00","08:35")} ## Innerhalb der Photovoltaik Zeit\ + - {sunset_abs("HORIZON=+8.0",0,"15:00","21:00")} ] and\ + [+([WR_1_API:Battery_ComMonitor_Time]-30)] ## Den Befehl nach eingestellter Zeit wiederholen\ + )\ + or [$SELF:ui_command_1] eq "Kommando_Wiederholung" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "Kommando_Wiederholung" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ +\ + my $MaxChargePowerTime = 0;;\ + my $MaxChargePowerAbs_midday = 0;;\ +\ + if (AttrVal("$SELF","verbose",0) >=4) { ## Hier können noch Testmeldungen hin\ + Log 3, "$SELF cmd_Test : SpeicherMiddayControlRunning ".[?$SELF:SpeicherMiddayControlRunning];;\ + Log 3, "$SELF cmd_Test : Yield_fc0_middayhigh_start ".[?WR_ctl:Yield_fc0_middayhigh_start];;\ + Log 3, "$SELF cmd_Test : Yield_fc0_middayhigh_stop ".[?WR_ctl:Yield_fc0_middayhigh_stop];;\ + }\ +\ + if ([?$SELF:SpeicherMiddayControlRunning] eq "An" ) { ## Wurde ein Mittagshoch ermittelt und aktiviert?\ +\ + if ( [?WR_1:Act_state_of_charge] >= [?WR_1_API:Battery_InternControl_MinSoc] *3 ) {\ + if ( time < ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?$SELF:SpeicherMidday_NotBefore].":00") ) {\ + ::CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs 0");; ## nicht vor z.B. 09:00 Uhr starten. Ladung auf 0 Watt setzen\ + if (AttrVal("$SELF","verbose",0) >=3) { ## Es wird nur langsam geladen und MaxSOC limitiert.\ + Log 3, "$SELF cmd_6 : SpeicherMiddayControl vor ".[?$SELF:SpeicherMidday_NotBefore]." Uhr noch nicht laden";;\ + }\ + } else { ## Ist noch Vormittag?\ + if ( time < ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_start].":00") ) {\ + ::CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs ".[?$SELF:SpeicherMidday_MaxChargePowerAbs_morning]);;\ + set_Exec("wait_ExternControl",4,'::CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel ".'.[?$SELF:SpeicherMidday_MaxSOC].')');;\ + if (AttrVal("$SELF","verbose",0) >=3) { ## Es wird nur langsam geladen und MaxSOC limitiert.\ + Log 3, "$SELF cmd_6 : SpeicherMiddayControl vor ".[?WR_ctl:Yield_fc0_middayhigh_start]." limitieren";;\ + Log 3, "$SELF cmd_6 : Battery_ExternControl_MaxChargePowerAbs auf ".[?$SELF:SpeicherMidday_MaxChargePowerAbs_morning]." limitiert";;\ + Log 3, "$SELF cmd_6 : Battery_ExternControl_MaxSOC auf ".[?$SELF:SpeicherMidday_MaxSOC]." % limitiert";;\ + }\ + }\ + }\ + } else {\ + Log 3, "$SELF cmd_6 : Battery_InternControl_MinSoc auf ".([?WR_1_API:Battery_InternControl_MinSoc] *3)." % laden";;\ + }\ +\ + if (::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_start].":00") <= time and ## Es ist Mittag\ + time <= ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_stop].":00") ) {\ +\ + my $wait = POSIX::strftime("%H:%M",localtime(::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_start].":00")+3600 ));;\ + $wait = POSIX::strftime("%H:%M",localtime(::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_start].":00") ));;\ +\ + if ([?$SELF:SpeicherMaxSOCControlRunning] eq "An" and ## Somit bleibt weniger Platz im Speicher und es ist\ + time < ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".$wait.":00") ) { ## besser nicht zu früh beginnen.\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_6 : SpeicherMiddayControlActive laden wegen MaxSoc von ".[?WR_ctl:Yield_fc0_middayhigh_start]." auf ".$wait." Uhr verschoben"};;\ +## Das wurde auskommentiert, damit das BEV mehr 70% Laden kann\ +## fhem("setreading WR_ctl Yield_fc0_middayhigh_start ".$wait);;\ +## ::CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs 0");;\ +\ + } else { ## auch jetzt nicht mit voller Leistung laden\ +\ + if ([?$SELF:SpeicherMidday_MaxChargePowerAbs_midday] == 0) { ## dynamische Leistungsermittlung oder vorgewählter Wert\ + $MaxChargePowerTime = ::round((::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_stop].":00") - time) / 3600 , 2);; ## Mittags Ladezeit bestimmen\ +\ + my $MaxChargePowerLimit = (1 - ::round($MaxChargePowerTime,2) * [?$SELF:SpeicherMidday_MaxChargePowerSteigung]);; ## Zu Beginn etwas langsamer anfangen, empirisch ermittelt\ +\ + $MaxChargePowerAbs_midday = ::round( [?WR_1:Battery_work_capacity] * ([?$SELF:SpeicherMaxSOC_Actual] - [?WR_1:Act_state_of_charge]) / 100 * $MaxChargePowerLimit, 0);;\ +\ +## Log 3, "$SELF cmd_6 : Test ".$MaxChargePowerTime." ".$MaxChargePowerLimit." ".$MaxChargePowerAbs_midday." vorher ".::round( [?WR_1:Battery_work_capacity] * ([?$SELF:SpeicherMaxSOC_Actual] - [?WR_1:Act_state_of_charge]) / 100 * (1 - ::round($MaxChargePowerTime,2) * [?$SELF:SpeicherMidday_MaxChargePowerSteigung]), 0);;\ +\ + if ($MaxChargePowerAbs_midday < 500) { $MaxChargePowerAbs_midday = 500 };;## Nicht unter 1000\ + Log 3, "$SELF cmd_6 : Mittags $MaxChargePowerTime h mit $MaxChargePowerAbs_midday W laden";;\ + } else {\ + $MaxChargePowerAbs_midday = [?$SELF:SpeicherMidday_MaxChargePowerAbs_midday];; ## Nimm den vorgewählten Wert\ + };;\ +\ + ::CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs $MaxChargePowerAbs_midday");;\ + set_Exec("wait_ExternControl",4,'::CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel ".'.[?$SELF:SpeicherMaxSOC_Actual].')');;\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF cmd_6 : SpeicherMiddayControlActive laden von ".[?WR_ctl:Yield_fc0_middayhigh_start]." bis ".[?WR_ctl:Yield_fc0_middayhigh_stop]." freigegeben";;\ + Log 3, "$SELF cmd_6 : Battery_ExternControl_MaxChargePowerAbs auf $MaxChargePowerAbs_midday limitiert";;\ + Log 3, "$SELF cmd_6 : Battery_ExternControl_MaxSocRel ".[?$SELF:SpeicherMaxSOC_Actual]." % halten"\ + };;\ + };;\ + };;\ +\ + if (time > ::time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." ".[?WR_ctl:Yield_fc0_middayhigh_stop].":00") ) { ## Es ist Nachmittag und die\ + set_Reading("SpeicherMiddayControlRunning","Aus");; ## Mittagssteuerung wird abgeschaltet\ + ::CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel ".[?$SELF:SpeicherMaxSOC_Actual]);;\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF cmd_6 : Battery_ExternControl_MaxSocRel ".[?$SELF:SpeicherMaxSOC_Actual]." % halten";;\ + Log 3, "$SELF cmd_6 : SpeicherMiddayControl nach ".[?WR_ctl:Yield_fc0_middayhigh_stop]." beendet";;\ + };;\ + };;\ + };;\ +\ + if (ReadingsVal("$SELF","SpeicherMaxSOCControlRunning","") eq "An" and ## Nur MaxSOC soll begrenzt werden\ + [$SELF:SpeicherMaxSOC_Actual] <= 100 and \ + ReadingsVal("$SELF","SpeicherMiddayControlRunning","") eq "Aus") { ## sobald die Mittagssteuerung fertig ist\ + if ([?WR_1:SW_Home_own_consumption_from_Battery] > 500) { ## Sollte der Speicher bereits jetzt verwendet werden ist es besser\ + set_Reading("SpeicherMaxSOCControlRunning","Aus");; ## die MaxSOC Begrenzung zu stoppen\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_6 : SpeicherMaxSOCControl wegen Speicher Nutzung am Nachmittag beendet"};;\ + } else {\ + ::CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel ".[?$SELF:SpeicherMaxSOC_Actual]);;\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_6 : Battery_ExternControl_MaxSocRel ".[?$SELF:SpeicherMaxSOC_Actual]." % halten"};;\ + };;\ + };;\ +\ + if (AttrVal("$SELF","verbose",0) >=4)\ + {Log 3, "$SELF cmd_6 : ExternControl Kommando Wiederholung erledigt"};;\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 7 Bestimmung eines möglichen SOC für den nächsten Morgen und\ +## Vorbereitung für ein Leistungshoch am Mittag\ +##\ +7_SOC_Calculation\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + (\ + ([WR_1_API:Battery_Control] > 0 and ## Ist die ExternControl am WR aktiviert\ + ([$SELF:SpeicherMaxSOCControlActive] eq "An" or ## Ist MaxSOC Limit konfiguriert\ + [$SELF:SpeicherMiddayControlActive] eq "An" ) and ## Ist Midday Kontrolle konfiguriert\ + [$SELF:SpeicherMaxSOC_MinSOC_Time] eq "NULL" and ## Wurde ein minimum SOC bereits ermittelt\ + [{sunrise_abs("HORIZON=+4.0",0,"5:50","08:35")} - 10:00 ] and\ + [WR_1:SW_Home_own_consumption_from_PV] == [WR_1:SW_Home_own_consumption] ## Die PV Leistung reicht für's Haus\ + )\ + or [$SELF:ui_command_1] eq "SOC_Calculation" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ + if( [?$SELF:ui_command_1] eq "SOC_Calculation" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ +\ + my $MinSOC_Time = "gefunden";; ## Nur einmal am Tag bearbeiten\ + my $MinSOC_MinSOC = ::round([?WR_1:Act_state_of_charge],0);; ## Festgestellter MinSOC am Morgen Magic ???\ + set_Reading("SpeicherMaxSOC_MinSOC_Time",$MinSOC_Time);;\ + set_Reading("SpeicherMaxSOC_MinSOC_MinSOC",$MinSOC_MinSOC);;\ + if (AttrVal("$SELF","verbose",0) >=3) { ## merken und melden\ + Log 3, "$SELF cmd_7 : SpeicherMaxSOC_MinSOC_Time ".$MinSOC_Time." ".$MinSOC_MinSOC." %";;\ + };;\ +\ +#############\ +\ + if ([?$SELF:SpeicherMaxSOCControlActive] eq "An" and\ + [?WR_1_API:Battery_InternControl_MinHomeConsumption] < 100 and ## Der Speicher darf nicht im smart_laden sein\ + [?Pool_Counter:countsPerDay] == 0 and ## Achtung der Pool und auch die LWP\ + [?LWP_Counter:countsPerDay] == 0 ) { ## sollten nicht mehr früh morgens laufen\ +\ + my $SpeicherSOCMinimum = [?WR_1_API:Battery_InternControl_MinSoc]*3;; ## 3x MinSOC als reserve vorsehen\ + my $SpeicherSOCDayBefore = ::round(ReadingsVal("$SELF","SpeicherMaxSOC_DayBefore", 100),0);; ## wie voll war er gestern noch?\ + my $SpeicherSOCNew = 0;;\ + my $SpeicherSOCDelta = 0;;\ +\ + if ([?WR_ctl:Yield_fc1_day] > [?$SELF:SpeicherMaxSOC_fc1_Limit] and\ + $MinSOC_MinSOC > $SpeicherSOCMinimum ) { ## Ist der Speicher voller als er müsste?\ +\ + if (AttrVal("$SELF","verbose",0) >=3){\ + Log 3, "$SELF cmd_7 : SpeicherMaxSOC_DayBefore ".$SpeicherSOCDayBefore." %";;\ + Log 3, "$SELF cmd_7 : Leistung Prognose ".[?WR_ctl:Yield_fc1_day]." wh > Schwellwert ".[?$SELF:SpeicherMaxSOC_fc1_Limit]." wh";;\ + Log 3, "$SELF cmd_7 : Speicherladung aktuell $MinSOC_MinSOC % > Minimum $SpeicherSOCMinimum %";;\ + };;\ + $SpeicherSOCDelta = $MinSOC_MinSOC - $SpeicherSOCMinimum;; ## Was wäre noch übrig?\ + if ($SpeicherSOCDelta <= 10) { ## Das lohnt sich nicht\ + $SpeicherSOCNew = $SpeicherSOCDayBefore;; ## den Wert von gestern einfach beibehalten\ + set_Reading("SpeicherMaxSOC_Actual",$SpeicherSOCDayBefore);;\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_7 : SpeicherMaxSOC_DayBefore ".$SpeicherSOCDayBefore." % gesichert"};;\ + } else {\ + $SpeicherSOCNew = ::round(($SpeicherSOCDayBefore+$SpeicherSOCDayBefore-$SpeicherSOCDelta)/2 ,0);; ## um den Durchschnitt verringern\ + set_Reading("SpeicherMaxSOC_Actual",$SpeicherSOCNew);; ## Das soll heute in den Speicher\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_7 : SpeicherMaxSOC_DayBefore ".$SpeicherSOCNew." % neu berechnet und gesichert"};;\ + };;\ +\ + if ($SpeicherSOCNew > 0) { ## Es gibt einen neuen MaxSoc\ + set_Reading("SpeicherMaxSOCControlRunning","An");; ## Senden starten\ + set_Reading("SpeicherCmdRepeatRunning","An");; ## Wiederholung starten\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_7 : SpeicherMaxSOC_Actual ".$SpeicherSOCNew." % geplant"};;\ + } else { ## MaxSoc wird nicht begrenzt\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_7 : SpeicherMaxSOC_Actual wird nicht begrenzt"};;\ + };;\ +\ + } else { ## MaxSoc wird nicht begrenzt\ + if ($MinSOC_MinSOC < $SpeicherSOCMinimum ) { ## MaxSoc leicht erhöhen, da er etwas zu niedrig war\ + $SpeicherSOCNew = ::round($SpeicherSOCDayBefore+$SpeicherSOCMinimum-$MinSOC_MinSOC ,0);;\ + $SpeicherSOCDelta = ::round($SpeicherSOCMinimum-$MinSOC_MinSOC ,0);;\ + set_Reading("SpeicherMaxSOC_DayBefore",$SpeicherSOCNew);;\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_7 : SpeicherMaxSOC_DayBefore wurde um ".$SpeicherSOCDelta." erhöht"};;\ + }\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_7 : SpeicherMaxSOC_Actual wird nicht begrenzt, da die Prognose für morgen zu schlecht ist"};;\ + };;\ + };;\ +\ + if ([?$SELF:SpeicherMiddayControlActive] eq "An" and ## Soll für mittags noch Platz gehalten werden?\ + [?WR_ctl:Yield_fc0_middayhigh] == 1 ) { \ + \ + set_Reading("SpeicherMiddayControlRunning","An");; ## Die Mittagskontrolle aktivieren\ + set_Reading("SpeicherCmdRepeatRunning","An");;\ + if (AttrVal("$SELF","verbose",0) >=3){ ## (die Uhrzeiten wurden bereits durch Solar_forecast() im WR_1 Device eingetragen)\ + Log 3, "$SELF cmd_7 : Batterie SpeicherMiddayControlRunning vorbereitet";;\ + Log 3, "$SELF cmd_7 : Batterie Yield_fc0_middayhigh_start ".ReadingsVal("WR_ctl","Yield_fc0_middayhigh_start", "00:00")." gesetzt";;\ + Log 3, "$SELF cmd_7 : Batterie Yield_fc0_middayhigh_stop ".ReadingsVal("WR_ctl","Yield_fc0_middayhigh_stop ", "00:00")." gesetzt";;\ + };;\ + } else { ## Kein Mittagshoch\ + Log 3, "$SELF cmd_7 : SpeicherMiddayControl es wird kein Middayhigh geben";;\ + };;\ +\ +#############\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 8 Reset der ExternControl Kommandos\ +##\ +8_Reset\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + [{sunset_abs("HORIZON=+8.0",0,"16:00","21:00")}] ## hier sollte das Ende der PV-Zeit sein\ + or [$SELF:ui_command_1] eq "Reset" ## Hier wird das uiTable select ausgewertet\ + ) {\ + if( [$SELF:ui_command_1] eq "Reset" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[$SELF:ui_command_1]);;\ + }\ +\ + set_Reading("SpeicherCmdRepeatRunning","Aus");; ## Stop das regelmäßige senden der Kommandos\ + \ + set_Reading("SpeicherMaxSOCControlRunning","Aus");; ## Max SOC Steuerung zurücksetzen\ + set_Reading("SpeicherMaxSOC_Actual","100");; ## SpeicherMaxSOC_Actual auf Default\ + set_Reading("SpeicherMaxSOC_DayBefore",[?WR_1:Act_state_of_charge]);; ## Den vor Tages Wert merken\ + set_Reading("SpeicherMaxSOC_MinSOC_Time","NULL");; ## Die MinSOC Time löschen\ + \ + set_Reading("SpeicherMiddayControlRunning","Aus");; ## Midday Steuerung zurücksetzen\ +\ + fhem("setreading WR_ctl Yield_fc0_middayhigh 0");;\ + fhem("setreading WR_ctl Yield_fc0_middayhigh_start 00:00");;\ + fhem("setreading WR_ctl Yield_fc0_middayhigh_stop 00:00");;\ +\ + fhem("setreading WR_ctl Yield_fc1_middayhigh 0");;\ + fhem("setreading WR_ctl Yield_fc1_middayhigh_start 00:00");;\ + fhem("setreading WR_ctl Yield_fc1_middayhigh_stop 00:00");;\ +\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_8 : ExternControl zurückgesetzt"};;\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 9 Umschaltung des MinSOC wenn zu wenig Leistung erwartet wird, das ist dann im Herbst/Winter\ +##\ +9_MinSOC_Winter\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ([WR_ctl:Yield_fc1_day] < [$SELF:SpeicherMinSOC_fc1_Limit] and ## Wenn morgen das Minimum an Leistung nicht erreicht wird\ + [WR_1_API:Battery_InternControl_MinSoc] < [$SELF:SpeicherMinSOC_Winter] and ## und der MinSoc unter der Winter Wert eingestellt ist\ + ([$SELF:SpeicherMaxSOC_MinSOC_Time] eq "gefunden" or\ + [$SELF:SpeicherMaxSOC_MinSOC_Time] eq "NULL" and [10:01])\ + )\ + or [$SELF:ui_command_1] eq "Winter" ## Hier wird das uiTable select ausgewertet\ + ) {\ + if( [?$SELF:ui_command_1] eq "Winter" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ +\ + ::CommandSet(undef, "WR_1_API 22_04_Battery_MinSoc ".[?$SELF:SpeicherMinSOC_Winter]);; ## Den MinSOC anheben, um eine eventuelle\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_9 : Batterie MinSoc auf Winterbetrieb"};; ## Notladung zu verhindern\ + set_Reading("SpeicherCmdRepeatRunning","Aus");; ## Stop das regelmäßige senden der Kommandos\ + set_Reading("SpeicherMaxSOCControlRunning","Aus");; ## Im Winter Betrieb keine MaxSOC Begrenzung\ + set_Reading("SpeicherMiddayControlRunning","Aus");; ## und keine Midday Steuerung\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_9 : MaxSOC Begrenzung und Midday Steuerung im Winterbetrieb deaktiviert"};;\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 10 Umschaltung des MinSoc wenn viel Leistung erwartet wir, das wäre dann Frühling/Sommer\ +##\ +10_MinSOC_Sommer\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ([WR_ctl:Yield_fc1_day] > [$SELF:SpeicherMinSOC_fc1_Limit] and ## sobald viel Ladung erwartet wird und der MinSoc noch\ + [WR_1_API:Battery_InternControl_MinSoc] > [$SELF:SpeicherMinSOC_Sommer] and ## noch im Winter Modus ist\ + [10:09] \ + )\ + or [$SELF:ui_command_1] eq "Sommer" ## Hier wird das uiTable select ausgewertet\ + ) {\ + if( [?$SELF:ui_command_1] eq "Sommer" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ + \ + ::CommandSet(undef, "WR_1_API 22_04_Battery_MinSoc ".[?$SELF:SpeicherMinSOC_Sommer]);; ## den MinSOC auf Sommerbetrieb herabsetzen, es kann\ + if (AttrVal("$SELF","verbose",0) >=3)\ + {Log 3, "$SELF cmd_10 : Batterie MinSoc auf Sommerbetrieb"};; ## wieder mehr Leistung genutzt werden\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 11 Der Speicher ist voll geladen. Hier wird das ständige nachladen auf 100 % vermieden.\ +##\ +11_Speicher_voll\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ( [WR_ctl:Yield_fc0_day] > [$SELF:SpeicherMaxSOC_fc1_Limit] and ## 1) sobald viel Leistung erwartet wird und der Speicher voll ist\ + [WR_1:Act_state_of_charge] == 100 and ## den MaxSOC wieder reduzieren, damit nicht immer nachgeladen wird\ + [$SELF:SpeicherMaxSOC_Actual] ne 95 ## \ + or\ + ([$SELF:SpeicherMaxSOC_Actual] == 95 and ## 2) oder das Nachladen gestoppt wurde\ + [WR_1:Act_state_of_charge] <= 98 and ## und der SOC unte 98 % gefallen ist\ + [{sunset_abs("HORIZON=+8.0",-7200,"15:00","21:00")}]) ## zwei Stunden vor Sonnenuntergang eventuell wieder nachladen\ + ) and [$SELF:ui_command_1] eq "---"\ + or [$SELF:ui_command_1] eq "Speicher_voll" ## Hier wird das uiTable select ausgewertet\ + ) {\ + if( [?$SELF:ui_command_1] eq "Speicher_voll" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ +\ + if ([?WR_1:Act_state_of_charge] <= 98) {\ + set_Reading("SpeicherMaxSOC_Actual","100");; ## Eventuell noch mal nachladen\ + set_Reading("SpeicherMaxSOCControlRunning","Aus");;\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF cmd_11 : Battery_ExternControl_MaxSocRel auf 100 % nachladen";;\ + };;\ + } else {\ + set_Reading("SpeicherMaxSOC_Actual","95");;\ + set_Reading("SpeicherCmdRepeatRunning","An");; ## Start regelmäßiges senden der Kommandos\ + set_Reading("SpeicherMaxSOCControlRunning","An");; ## MaxSOC Begrenzung weil Speicher bereits 100 % hat\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF cmd_11 : Battery_ExternControl_MaxSocRel auf 95 % reduziert";;\ + };;\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 12 WR_1_Speicher_1 DC_Power_Abs setzen z.B. zur Zwangsentladung\ +## dies muss manuell wiederholt werden. Danach hängt es vom WR ab, wie er die Speichersteuerung fortsetzt.\ +12_DC_Power_Abs \ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + [$SELF:ui_command_1] eq "DC_Power_Abs" ## Hier wird das uiTable select ausgewertet\ + ) {\ + if( [?$SELF:ui_command_1] eq "DC_Power_Abs" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ +\ + ::CommandSet(undef, "WR_1_API 23_05_Battery_ExternControl_DcPowerAbs ".[?$SELF:SpeicherDcPowerAbs]);;\ +\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF cmd_12 : Battery_ExternControl_DcPowerAbs auf ".[?$SELF:SpeicherDcPowerAbs]." gesetzt";;\ + };;\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 6 Wiederhole alle 180s die Kommandos der ExternControl Steuerung\ +##\ +16_Stop_Standby_Entladung\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ((\ + [WR_1_API:Battery_Control] > 0 and ## Wenn die ExternControl am WR konfiguriert ist\ + [$SELF:SpeicherCmdRepeatActive] eq "An" and ## Wenn die ExternControl Aktiviert ist\ + [$SELF:SpeicherExternTrigger] eq "gesperrt" and ## Das smart_Laden\ + [WR_1_API:Battery_InternControl_MinHomeConsumption] == 30000 and ## aktiviert wurde\ + [WR_1:Total_Active_P_EM] > 0 and ## Es wird nicht ins Netz eingespeist\ + [$SELF:SpeicherDcPowerAbs] == 5000 and ## Es wird anderweitig kein Wert vorgegeben <<< ist nicht mehr aktiv\ + [+([WR_1_API:Battery_ComMonitor_Time]-30)] ## Den Befehl nach eingestellter Zeit wiederholen\ + )\ + or [$SELF:ui_command_1] eq "Stop_Standby_Entladung" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "Stop_Standby_Entladung" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ +\ + ::CommandSet(undef, "WR_1_API 23_05_Battery_ExternControl_DcPowerAbs -10");;\ + set_Exec("16_Battery_EM_State",30,'::CommandGet(undef, "WR_1_API 25_Battery_EM_State")');;\ +\ + if (AttrVal("$SELF","verbose",0) >=4) {\ + Log 3, "$SELF cmd_16 : Battery_ExternControl_DcPowerAbs auf -10 gesetzt";;\ + };;\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 17 Wiederhole alle 180s das Kommando für die DcPowerAbs Steuerung\ +##\ +17_Kommando_Wiederholung_DcPowerAbs\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ((\ + [$SELF:SpeicherTriggerLaden] eq "An" ## Ist der Trigger für das Zwangsladen aktiv?\ + and [$SELF:SpeicherDcPowerAbs] ne 0 ## Wurde eine Lade/Entlade Leistung eingestellt?\ + and ( [+58] ## Den Befehl nach eingestellter Zeit wiederholen\ + or [$SELF:SpeicherDcPowerAbs]\ + )\ + )\ + or [$SELF:ui_command_1] eq "Kommando_Wiederholung_DcPowerAbs" ## Hier wird das uiTable select ausgewertet\ + or [$SELF:SpeicherTriggerLaden] eq "Aus" ## Hier wird die externe Steuerung beendet\ + and [$SELF:SpeicherDcPowerAbs] ne 0\ + )\ + ) {\ +\ + if( [?$SELF:ui_command_1] eq "Kommando_Wiederholung_DcPowerAbs" ) { ## Hier wurde manuell eingeschaltet\ + set_Reading("ui_command_1_before",[?$SELF:ui_command_1]);;\ + }\ + if([?$SELF:SpeicherTriggerLaden] eq "An") {\ + set_Exec("17_Battery_EM_State",30,'::CommandGet(undef, "WR_1_API 25_Battery_EM_State")');;\ + } else {\ + set_Reading("SpeicherDcPowerAbs",0);;\ +\ + set_Exec("17_Battery_ComMonitor_Time",90,'::CommandSet(undef, "WR_1_API 23_12_Battery_ComMonitor_Time '.[?WR_1_API:Battery_ComMonitor_Time].'")');;\ + ::CommandSet(undef, "WR_1_API 23_12_Battery_ComMonitor_Time 60");;\ +\ + set_Exec("17_Battery_EM_State",90,'::CommandGet(undef, "WR_1_API 25_Battery_EM_State");;Log 3, "$SELF cmd_17 : 25_Battery_EM_State abgerufen"');;\ + }\ +\ + ::CommandSet(undef, "WR_1_API 23_05_Battery_ExternControl_DcPowerAbs [?$SELF:SpeicherDcPowerAbs]");;\ + set_Exec("17_Repeat_CMD",13,'::CommandSet(undef, "WR_1_API 23_05_Battery_ExternControl_DcPowerAbs '.[?$SELF:SpeicherDcPowerAbs].'")');;\ +\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF cmd_17 : Battery_ExternControl_DcPowerAbs auf ".[?$SELF:SpeicherDcPowerAbs]." gesetzt";;\ + };;\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 18 SpeicherStromboerse\ +##\ +18_SpeicherStromboerse\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ((\ + [$SELF:SpeicherStromboerse] eq "Tibber" ## Soll Tibber verwendet werden?\ + and [EVU_Tibber_connect:fc0_trigger] ## Wurde der Trigger geändert\ +\ + )\ + or [$SELF:ui_command_1] eq "SpeicherStromboerse" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + if ([?EVU_Tibber_connect:fc0_trigger] eq "on") {\ + set_Reading("SpeicherDcPowerAbs",[?$SELF:SpeicherStromboerseDcPowerAbs]);;\ + fhem("setreading $SELF SpeicherTriggerLaden An");;\ + } else {\ + fhem("setreading $SELF SpeicherTriggerLaden Aus");;\ + fhem("setreading $SELF SpeicherDcPowerAbs 0");;\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +} +attr WR_1_Speicher_1_ExternControl DbLogExclude .* +attr WR_1_Speicher_1_ExternControl alias WR_1_Speicher_1_ExternControl +attr WR_1_Speicher_1_ExternControl comment Version 2023.06.21 14:00\ +\ +Hier können externe Trigger für die Ladung und Entladung Der Batterie gesetzt werden.\ +Die Zeiten können z.B. durch den WeekDayTimer entsprechend an einen Stromtarif angepasst werden.\ +Das reading SpeicherEntladung Automatik/Zeit/SpeicherTrigger ermöglicht es die Zeitsteuerung zu überschreiben.\ +\ +ExternTrigger\ +Das reading dient dem Freigeben und Sperren der externen Trigger, z.B. um im Herbst/Winter das smart_laden zu steuern.\ +Es verriegelt somit die Zeitsteuerung oder den SpeicherTrigger.\ +\ +SpeicherEntladung:Automatik,Zeit,SpeicherTrigger \ +Automatik - Der Speicher wird vom Wechselrichter gesteuert, oder über die eigene ExternControl der API\ +Zeit - Das Laden und Entladen wird mit den Zeitwerten beeinflusst\ +SpeicherTrigger - beeinflusst das Laden und Entladen direkt ohne die Zeitsteuerung\ +\ +SpeicherTrigger:entladen,gesperrt\ +Dieser Trigger kann durch ander Logik gesetzt werden.\ +Auch hier wäre eine Zeitsteuerung denkbar, die entladen/gesperrt entsprechend umschaltet.\ +\ +SpeicherZeitStart/SpeicherZeitEnde\ +Die Zeitangaben können manuell fest gesetzt werden, oder über zusätzliche Timer täglich neu überschrieben werden.\ +Eine gültige Zeit und entsprechendes Timeing obliegt dem Anwender.\ +Zwischen Start und Ende wird der Speicher zum Entladen freigegeben und zwischen Ende und Start gesperrt.\ +\ +Speicher*ControlActive\ +Das jeweilige reading aktiviert diese Teilkomponente für die Steuerung.\ +Ein jeweiliges Speicher*ControlRunning signalisiert, ob gerade die Bedingungen erfüllt sind.\ +\ +SpeicherCmdRepeatActive\ +Es muss im WR die externe Speicher Steuerung aktiviert sein.\ +Möchte man trotzdem die Sendung der ExternControl Kommandos stoppen, obwohl die Bedingungen erfüllt sind,\ +kann man dieses reading zum Deaktivieren auf 0 setzen.\ +\ +SpeicherMiddayControl\ +Über die Solar_forecast() Funktion wird ein Middayhigh ermittelt, wenn der WR nur 70% einspeisen darf.\ +\ +SpeicherMaxSOCControl\ +Es wird versucht den Speicher am Abend nicht zu 100% zu laden, aber morgens noch mit 3* MinSOC aus der Nacht zu kommen.\ +\ +SpeicherMinSOC\ +Dies gehört zur Basis Steuerung und schaltet den MinSOC von Sommer auf Winter Betrieb,\ +um eine Notladung aus dem Netz zu vermeiden. +attr WR_1_Speicher_1_ExternControl disable 0 +attr WR_1_Speicher_1_ExternControl group PV Eigenverbrauch +attr WR_1_Speicher_1_ExternControl icon measure_battery_100 +attr WR_1_Speicher_1_ExternControl readingList SpeicherExternTrigger SpeicherCmdRepeatActive SpeicherZeitStart SpeicherZeitEnde SpeicherEntladung SpeicherTrigger SpeicherMiddayControlActive SpeicherMidday_Inverter_Max_Power SpeicherMidday_MaxChargePowerAbs_morning SpeicherMidday_MaxChargePowerAbs_midday SpeicherMidday_MaxChargePowerSteigung SpeicherMidday_MaxSOC SpeicherMidday_NotBefore SpeicherMinSOC_Sommer SpeicherMinSOC_Winter SpeicherMinSOC_fc1_Limit SpeicherMaxSOCControlActive SpeicherMaxSOC_Actual SpeicherMaxSOC_DayBefore SpeicherMaxSOC_fc1_Limit +attr WR_1_Speicher_1_ExternControl room 2_PV_Steuerung,Strom->Photovoltaik +attr WR_1_Speicher_1_ExternControl setList SpeicherExternTrigger:frei,gesperrt SpeicherCmdRepeatActive:0,1 SpeicherZeitStart:time SpeicherZeitEnde:time SpeicherEntladung:Automatik,Zeit,Trigger SpeicherTrigger:entladen,gesperrt,none SpeicherMiddayControlActive:0,1 SpeicherMidday_Inverter_Max_Power:slider,3000,500,20000 SpeicherMidday_MaxChargePowerAbs_morning:slider,0,50,1000 SpeicherMidday_MaxChargePowerAbs_midday:slider,0,100,4700 SpeicherMidday_MaxChargePowerSteigung SpeicherMidday_MaxSOC:slider,20,5,50 SpeicherMidday_NotBefore:time SpeicherMinSOC_Sommer:slider,5,1,20 SpeicherMinSOC_Winter:slider,5,1,20 SpeicherMinSOC_fc1_Limit:slider,7000,500,17000 SpeicherMaxSOCControlActive:0,1 SpeicherMaxSOC_Actual:slider,60,5,100 SpeicherMaxSOC_DayBefore:slider,15,5,100 SpeicherMaxSOC_fc1_Limit:slider,10000,2000,50000 +attr WR_1_Speicher_1_ExternControl sortby 122 +attr WR_1_Speicher_1_ExternControl uiTable {\ +package ui_Table;;\ +## $TR{0} = "style='color:yellow;;text-align:left;;font-weight:bold;;font-size:18px'";; ## Reihe 0 für Überschrift\ + $TABLE = "style='width:100%;;'";;\ +\ + $TD{0..9}{0} = "align='center' style='font-size:16px;;border-right-style:solid;;border-color:darkgreen;;border-right-width:2px;;width:26%'";;\ +\ + $TD{0..9}{1} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ + $TD{0..9}{2..4} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ + $TD{0..9}{5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ +\ +sub FUNC_batt {\ + my($val)=@_;;\ + my $ret="position:absolute;;left:".(90*$val/100)."px;;width:90px;;height:20px;;background:linear-gradient( to right,#F8F8E0 ".(90-(90*$val/100))."px,rgba(0,0,0,0) ".(90-(90*$val/100))."px);;";;\ + return $ret;;\ + }\ +sub FUNC_Status {\ + my($value, $min, $colorMin, $statusMin, $colorMiddel, $statusMiddle, $max, $colorMax, $statusMax)=@_;;\ + my $ret = ($value < $min)? ''.$statusMin.'' : ($value > $max)? ''.$statusMax.'' : ''.$statusMiddle.'';;\ + return $ret;;\ + }\ +\ +sub Device {\ + return "EVU_Tibber_connect";;\ + }\ +\ +sub Format {\ + my($i)=@_;;\ +\ + if ($i eq "trigger_0") {\ + return ( ::ReadingsVal(Device(),"fc_min",0) > ::ReadingsVal(Device(),"fc_trigger_price",0)\ + or ::ReadingsVal(Device(),"fc0_trigger_start","") eq "null" ) ?\ + "Heute kein Trigger
mehr unter ".\ + ::ReadingsVal(Device(),"fc_trigger_price","null")." ct
" :\ + "Trigger von
".\ + ::ReadingsVal(Device(),"fc0_trigger_start","00:00")." bis ".::ReadingsVal(Device(),"fc0_trigger_stop","00:00")."
unter ".\ + ::ReadingsVal(Device(),"fc_trigger_price","null")." ct
" ;;\ + } elsif ($i eq "trigger_1") {\ + return ( ::ReadingsVal(Device(),"fc_min",0) > ::ReadingsVal(Device(),"fc_trigger_price",0)\ + or ::ReadingsVal(Device(),"fc1_trigger_start","") eq "null" ) ?\ + "Morgen kein Trigger
mehr unter ".\ + ::ReadingsVal(Device(),"fc_trigger_price","null")." ct
" :\ + "Morgen ein Trigger von
".\ + ::ReadingsVal(Device(),"fc1_trigger_start","00:00")." bis ".::ReadingsVal(Device(),"fc1_trigger_stop","00:00")."
unter ".\ + ::ReadingsVal(Device(),"fc_trigger_price","null")." ct
" ;;\ + }\ + return "null";;\ + }\ +}\ +\ +#########################################################\ +## "Spalte 0"|"Spalte 1"|"Spalte 2"|"Spalte 3"|"Spalte 4"|"Spalte 5"\ +\ +"$SELF"|"Kommando
Auswahl / DcPowerAbs / Status
" | widget([$SELF:ui_command_1],"uzsuDropDown,---,Status_Speicher,smart_Laden_start,smart_Laden_beenden,smart_Laden_starten_WB,smart_Laden_beenden_WB,Kommando_Wiederholung,SOC_Calculation,Reset,DC_Power_Abs,Sommer,Winter,Speicher_voll,14_Luefter_ein,15_Luefter_aus,Status_WR_1_Speicher_1_BYD") | widget([$SELF:SpeicherDcPowerAbs],"selectnumbers,-4500,250,4500,0,lin")."W".widget([$SELF:SpeicherTriggerLaden],"uzsuDropDown,An,Aus,manuell") |[WR_1_API:Battery_EM_State]|([$SELF:SpeicherExternTrigger] eq "gesperrt" and [WR_1_API:Battery_InternControl_MinHomeConsumption] == 30000)?'smart_Laden aktiv':""\ +\ +|"Speicher
Steuerung
" | widget([$SELF:SpeicherEntladung],"uzsuDropDown,Automatik,Trigger,Zeit") |"WB Laden ".widget([$SELF:SpeicherWB_buffer],"uzsuToggle,Aus,An")|\ +FUNC_Status([WR_1:Actual_Battery_charge_-minus_or_discharge_-plus_P],-10,"green","Laden","orange","Standby",15,"red","Entladen")."
".FUNC_Status([WR_1:Act_state_of_charge],15,"red","Speicher SOC","orange","Speicher SOC",49,"green","Speicher SOC")|\ +\ + FUNC_Status([WR_1:Actual_Battery_charge_-minus_or_discharge_-plus_P],-10,"green",[WR_1:Actual_Battery_charge_-minus_or_discharge_-plus_P],"orange",[WR_1:Actual_Battery_charge_-minus_or_discharge_-plus_P],15,"red",[WR_1:Actual_Battery_charge_-minus_or_discharge_-plus_P])." W"."
".STY(" ",FUNC_batt([WR_1:Act_state_of_charge])).STY(::round([WR_1:Act_state_of_charge],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."
"\ +\ +\ +|"Trigger
Status / ExternTrigger / Start / Ende
" | widget([$SELF:SpeicherTrigger],"uzsuDropDown,entladen,gesperrt,none") | widget([$SELF:SpeicherExternTrigger],"uzsuDropDown,frei,gesperrt,none") | widget([$SELF:SpeicherZeitStart],"time") | widget([$SELF:SpeicherZeitEnde],"time")\ +\ +|"Strombörse
Auswahl/Ladeleistung / Ladefenster fc0/fc1 / Trigger Status
" | widget([$SELF:SpeicherStromboerse],"uzsuDropDown,Aus,Tibber")."
".widget([$SELF:SpeicherStromboerseDcPowerAbs],"selectnumbers,-4500,250,0,0,lin")."W" | \ +"Trigger fc0

".Format("trigger_0")|\ +"Trigger fc1

".Format("trigger_1")|\ +[EVU_Tibber_connect:fc0_trigger] \ +\ +|"Kommando Wiederholung
aktiviert / läuft
" | widget([$SELF:SpeicherCmdRepeatActive],"uzsuToggle,Aus,An") | widget([$SELF:SpeicherCmdRepeatRunning],"uzsuToggle,Aus,An") |""|""\ +\ +|"MaxSOC Kontrolle
aktiviert / läuft
" | widget([$SELF:SpeicherMaxSOCControlActive],"uzsuToggle,Aus,An") | widget([$SELF:SpeicherMaxSOCControlRunning],"uzsuToggle,Aus,An") |""|""\ +\ +|"MaxSOC Limit
fc1_Limit / Minimum SOC Zeit / gestern / geplant
" |\ +FUNC_Status([WR_ctl:Yield_fc1_day],[$SELF:SpeicherMaxSOC_fc1_Limit],"red","<",0,0,([$SELF:SpeicherMaxSOC_fc1_Limit]-1),"green",">="). widget([$SELF:SpeicherMaxSOC_fc1_Limit],"selectnumbers,2000,1000,40000,0,lin") | ([$SELF:SpeicherMaxSOC_MinSOC_Time] eq "gefunden")?(POSIX::strftime("%H:%M",::localtime(::time_str2num(::ReadingsTimestamp("$SELF","SpeicherMaxSOC_MinSOC_MinSOC",""))))." ".[$SELF:SpeicherMaxSOC_MinSOC_MinSOC]." %"):"wartet" |\ +"
".STY(" ",FUNC_batt([$SELF:SpeicherMaxSOC_DayBefore])).STY("gestern","font-size:12px;;position:absolute;;top:3px;;left:25px")."
".widget([$SELF:SpeicherMaxSOC_DayBefore],"selectnumbers,5,1,100,0,lin")."%" |\ +"
".STY(" ",FUNC_batt([$SELF:SpeicherMaxSOC_Actual])).STY("geplant","font-size:12px;;position:absolute;;top:3px;;left:25px")."
".widget([$SELF:SpeicherMaxSOC_Actual],"selectnumbers,5,1,100,0,lin")."%"\ +\ +|"Mittags Kontrolle
aktiviert / läuft
" | widget([$SELF:SpeicherMiddayControlActive],"uzsuToggle,Aus,An") | widget([$SELF:SpeicherMiddayControlRunning],"uzsuToggle,Aus,An")|""|""\ +\ +|"Mittags Limits
Inverter_Max_Power / Laden nicht vor / Start /Stop
MaxSOC morgens / Power morgens / Power mittags
" | widget([$SELF:SpeicherMidday_Inverter_Max_Power],"selectnumbers,1000,250,15000,0,lin")."W
".widget([$SELF:SpeicherMidday_MaxSOC],"selectnumbers,5,1,100,0,lin")."%" | widget([$SELF:SpeicherMidday_NotBefore],"time").widget([$SELF:SpeicherMidday_MaxChargePowerAbs_morning],"selectnumbers,0,50,1000,0,lin")."W" | widget([WR_ctl:Yield_fc0_middayhigh_start],"time").widget([$SELF:SpeicherMidday_MaxChargePowerAbs_midday],"selectnumbers,0,100,4700,0,lin")."W" | widget([WR_ctl:Yield_fc0_middayhigh_stop],"time").([$SELF:SpeicherMidday_MaxChargePowerAbs_midday] == 0)?"dynamisch":""\ +\ +|"MinSOC Steuerung
fc1_Limit / Winter | Sommer /aktuell
"|\ + FUNC_Status([WR_ctl:Yield_fc1_day],[$SELF:SpeicherMinSOC_fc1_Limit],"red","<",0,0,([$SELF:SpeicherMinSOC_fc1_Limit]-1),"green",">=").widget([$SELF:SpeicherMinSOC_fc1_Limit],"selectnumbers,2000,1000,40000,0,lin")."wh" |\ + widget([$SELF:SpeicherMinSOC_Winter],"selectnumbers,10,1,30,0,lin").widget([$SELF:SpeicherMinSOC_Sommer],"selectnumbers,5,1,10,0,lin")."%" |""|[WR_1_API:Battery_InternControl_MinSoc]." %" +attr WR_1_Speicher_1_ExternControl verbose 3 + +setstate WR_1_Speicher_1_ExternControl 2023-02-28 10:09:32 SpeicherCmdRepeatActive An +setstate WR_1_Speicher_1_ExternControl 2024-01-24 16:00:00 SpeicherCmdRepeatRunning Aus +setstate WR_1_Speicher_1_ExternControl 2024-01-19 11:21:57 SpeicherDcPowerAbs 0 +setstate WR_1_Speicher_1_ExternControl 2022-12-18 11:28:13 SpeicherEntladung Automatik +setstate WR_1_Speicher_1_ExternControl 2024-01-24 11:37:02 SpeicherExternTrigger none +setstate WR_1_Speicher_1_ExternControl 2023-02-28 10:09:31 SpeicherMaxSOCControlActive An +setstate WR_1_Speicher_1_ExternControl 2024-01-24 16:00:00 SpeicherMaxSOCControlRunning Aus +setstate WR_1_Speicher_1_ExternControl 2024-01-24 16:00:00 SpeicherMaxSOC_Actual 100 +setstate WR_1_Speicher_1_ExternControl 2024-01-24 16:00:00 SpeicherMaxSOC_DayBefore 93.00 +setstate WR_1_Speicher_1_ExternControl 2024-01-24 09:13:02 SpeicherMaxSOC_MinSOC_MinSOC 67 +setstate WR_1_Speicher_1_ExternControl 2024-01-24 16:00:00 SpeicherMaxSOC_MinSOC_Time NULL +setstate WR_1_Speicher_1_ExternControl 2021-12-03 10:38:43 SpeicherMaxSOC_fc1_Limit 30000 +setstate WR_1_Speicher_1_ExternControl 2023-02-28 10:09:29 SpeicherMiddayControlActive An +setstate WR_1_Speicher_1_ExternControl 2024-01-24 16:00:00 SpeicherMiddayControlRunning Aus +setstate WR_1_Speicher_1_ExternControl 2023-06-15 12:35:46 SpeicherMidday_Inverter_Max_Power 9000 +setstate WR_1_Speicher_1_ExternControl 2022-08-07 14:40:51 SpeicherMidday_MaxChargePowerAbs_midday 0 +setstate WR_1_Speicher_1_ExternControl 2023-02-07 13:24:17 SpeicherMidday_MaxChargePowerAbs_morning 450 +setstate WR_1_Speicher_1_ExternControl 2022-08-24 14:43:16 SpeicherMidday_MaxChargePowerSteigung 0.25 +setstate WR_1_Speicher_1_ExternControl 2021-12-03 10:39:28 SpeicherMidday_MaxSOC 30 +setstate WR_1_Speicher_1_ExternControl 2022-03-03 09:21:27 SpeicherMidday_NotBefore 09:00 +setstate WR_1_Speicher_1_ExternControl 2022-02-28 18:45:27 SpeicherMinSOC_Sommer 5 +setstate WR_1_Speicher_1_ExternControl 2023-10-25 14:26:37 SpeicherMinSOC_Winter 10 +setstate WR_1_Speicher_1_ExternControl 2022-12-19 18:27:53 SpeicherMinSOC_fc1_Limit 16000 +setstate WR_1_Speicher_1_ExternControl 2023-12-09 07:45:25 SpeicherStromboerse Aus +setstate WR_1_Speicher_1_ExternControl 2023-12-08 12:51:40 SpeicherStromboerseDcPowerAbs -4500 +setstate WR_1_Speicher_1_ExternControl 2022-12-14 07:00:00 SpeicherTrigger entladen +setstate WR_1_Speicher_1_ExternControl 2024-01-19 11:21:57 SpeicherTriggerLaden Aus +setstate WR_1_Speicher_1_ExternControl 2024-01-09 17:23:01 SpeicherWB_buffer Aus +setstate WR_1_Speicher_1_ExternControl 2022-12-13 16:51:11 SpeicherZeitEnde 17:00 +setstate WR_1_Speicher_1_ExternControl 2023-01-09 11:44:35 SpeicherZeitStart 07:00 +setstate WR_1_Speicher_1_ExternControl 2024-01-22 05:30:39 WB_smart_laden_before --- +setstate WR_1_Speicher_1_ExternControl 2024-01-24 16:00:00 ui_command_1 --- +setstate WR_1_Speicher_1_ExternControl 2024-01-20 09:28:57 ui_command_1_before --- diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_2.txt b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_2.txt new file mode 100644 index 000000000..2b477617d --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_2.txt @@ -0,0 +1,109 @@ +defmod WR_2 ModbusAttr 71 60 192.168.178.19:1502 TCP +attr WR_2 DbLogExclude .* +attr WR_2 DbLogInclude P_DC1,P_DC2,P_DC3,Total_.*,P_limit_from_EVU.* +attr WR_2 alias WR_2 +attr WR_2 alignTime 00:00 +attr WR_2 comment Version 2021.06.02 14:00\ +Kostal Plenticore Plus 7 +attr WR_2 dev-h-combine 8 +attr WR_2 dev-h-defFormat %.2f +attr WR_2 dev-h-defLen 2 +attr WR_2 dev-h-defPoll 1 +attr WR_2 dev-h-defRevRegs 1 +attr WR_2 dev-h-defUnpack f> +attr WR_2 dev-type-STR-format %s +attr WR_2 dev-type-STR-len 8 +attr WR_2 dev-type-STR-revRegs 0 +attr WR_2 dev-type-STR-unpack a* +attr WR_2 disable 0 +attr WR_2 event-on-change-reading P_DC1,P_DC2,P_DC3,Total_.*,Inverter_state.*,Inverter_Generation_P_Actual.*,P_limit_from_EVU.* +attr WR_2 group PV Eigenverbrauch +attr WR_2 icon sani_solar +attr WR_2 obj-h100-reading Total_DC_P +attr WR_2 obj-h1056-reading Total_DC_PV_Energy_sumOfAllPVInputs +attr WR_2 obj-h1058-reading Total_DC_Energy_From_PV1 +attr WR_2 obj-h1060-reading Total_DC_Energy_From_PV2 +attr WR_2 obj-h1062-reading Total_DC_Energy_From_PV3 +attr WR_2 obj-h1064-reading Total_AC_Energy_ACsideToGrid +attr WR_2 obj-h1066-reading Total_DC_P_sumOfAllPVInputs +attr WR_2 obj-h120-reading Isolation_resistance +attr WR_2 obj-h122-reading P_limit_from_EVU +attr WR_2 obj-h14-reading Inverter_serial_number +attr WR_2 obj-h14-type STR +attr WR_2 obj-h144-reading Worktime +attr WR_2 obj-h150-reading Actual_cos_phi +attr WR_2 obj-h152-reading Grid_frequency +attr WR_2 obj-h154-reading I_L1 +attr WR_2 obj-h156-reading Active_P_L1 +attr WR_2 obj-h158-reading U_L1 +attr WR_2 obj-h160-reading I_L2 +attr WR_2 obj-h162-reading Active_P_L2 +attr WR_2 obj-h164-reading U_L2 +attr WR_2 obj-h166-reading I_L3 +attr WR_2 obj-h168-reading Active_P_L3 +attr WR_2 obj-h170-reading U_L3 +attr WR_2 obj-h172-reading Total_AC_Active_P +attr WR_2 obj-h174-reading Total_AC_Reactive_P +attr WR_2 obj-h178-reading Total_AC_Apparent_P +attr WR_2 obj-h202-reading PSSB_fuse_state +attr WR_2 obj-h254-reading Total_Reactive_P_EM +attr WR_2 obj-h258-reading I_DC1 +attr WR_2 obj-h260-reading P_DC1 +attr WR_2 obj-h266-reading U_DC1 +attr WR_2 obj-h268-reading I_DC2 +attr WR_2 obj-h270-reading P_DC2 +attr WR_2 obj-h276-reading U_DC2 +attr WR_2 obj-h278-reading I_DC3 +attr WR_2 obj-h280-reading P_DC3 +attr WR_2 obj-h286-reading U_DC3 +attr WR_2 obj-h320-reading Total_yield +attr WR_2 obj-h322-reading Daily_yield +attr WR_2 obj-h324-reading Yearly_yield +attr WR_2 obj-h326-reading Monthly_yield +attr WR_2 obj-h38-reading Software-Version_Maincontroller_MC +attr WR_2 obj-h38-type STR +attr WR_2 obj-h384-len 16 +attr WR_2 obj-h384-reading Inverter_network_name +attr WR_2 obj-h384-type STR +attr WR_2 obj-h420-reading IP-address +attr WR_2 obj-h420-type STR +attr WR_2 obj-h428-reading IP-subnetmask +attr WR_2 obj-h428-type STR +attr WR_2 obj-h436-reading IP-gateway +attr WR_2 obj-h436-type STR +attr WR_2 obj-h446-reading IP-DNS1 +attr WR_2 obj-h446-type STR +attr WR_2 obj-h454-reading IP-DNS2 +attr WR_2 obj-h454-type STR +attr WR_2 obj-h46-reading Software-Version_IO-Controller_IOC +attr WR_2 obj-h46-type STR +attr WR_2 obj-h529-len 4 +attr WR_2 obj-h529-reading Work_Capacity +attr WR_2 obj-h529-unpack N +attr WR_2 obj-h531-format %.0f +attr WR_2 obj-h531-reading Inverter_Max_P +attr WR_2 obj-h531-unpack N +attr WR_2 obj-h535-revRegs 0 +attr WR_2 obj-h535-unpack n +attr WR_2 obj-h551-revRegs 0 +attr WR_2 obj-h559-revRegs 0 +attr WR_2 obj-h56-format %.0f +attr WR_2 obj-h56-reading Inverter_state +attr WR_2 obj-h56-unpack N +attr WR_2 obj-h575-reading Inverter_Generation_P_Actual +attr WR_2 obj-h575-unpack N +attr WR_2 obj-h577-len 2 +attr WR_2 obj-h577-reading Generation_Energy +attr WR_2 obj-h577-unpack N +attr WR_2 obj-h578-reading Total_energy +attr WR_2 obj-h6-reading Inverter_Article_number +attr WR_2 obj-h6-type STR +attr WR_2 obj-h768-len 32 +attr WR_2 obj-h768-reading Productname +attr WR_2 obj-h768-type STR +attr WR_2 obj-h800-len 32 +attr WR_2 obj-h800-reading Power_class +attr WR_2 obj-h800-type STR +attr WR_2 room Strom->Photovoltaik +attr WR_2 sortby 211 +attr WR_2 verbose 0 \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_2_API.txt b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_2_API.txt new file mode 100644 index 000000000..261931a36 --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_2_API.txt @@ -0,0 +1,328 @@ +defmod WR_2_API HTTPMOD http://%IP-WR%/api/v1/auth/me 0 +attr WR_2_API DbLogExclude .* +attr WR_2_API DbLogInclude Statistic_EnergyPv[1|2|3].*,Statistic_Yield.* +attr WR_2_API authRetries 1 +attr WR_2_API comment Version 2021.04.27 16:00\ +Passworte für die Abfrage des WR_2_API werden im storeKeyValue abgelegt:\ + {KeyValue("[read|store]","PW__","")}\ + {KeyValue("store","PW_WR_2_API_user","")} +attr WR_2_API disable 0 +attr WR_2_API dontRequeueAfterAuth 0 +attr WR_2_API enableControlSet 0 +attr WR_2_API enableCookies 1 +attr WR_2_API event-on-update-reading auth_.*,Statistic_EnergyPv[1|2|3].*,Statistic_Yield.* +attr WR_2_API get01Data %START% +attr WR_2_API get01Name 01_auth_start +attr WR_2_API get01URL http://%IP-WR%/api/v1/auth/start +attr WR_2_API get02Data %FINISH% +attr WR_2_API get02Name 02_auth_finish +attr WR_2_API get02URL http://%IP-WR%/api/v1/auth/finish +attr WR_2_API get03Data %SESSION% +attr WR_2_API get03Name 03_auth_create_session +attr WR_2_API get03URL http://%IP-WR%/api/v1/auth/create_session +attr WR_2_API get04-1Name auth_me_active +attr WR_2_API get04-2Name auth_me_locked +attr WR_2_API get04-3Name auth_me_authenticated +attr WR_2_API get04-4Name auth_me_anonymous +attr WR_2_API get04-5Name auth_me_role +attr WR_2_API get04-6Name auth_me_permissions +attr WR_2_API get04Header authorization: Session %auth_sessionId% +attr WR_2_API get04JSON . +attr WR_2_API get04Name 04_auth_me +attr WR_2_API get04URL http://%IP-WR%/api/v1/auth/me +attr WR_2_API get05-1Name info_api_version +attr WR_2_API get05-2Name info_hostname +attr WR_2_API get05-3Name info_name +attr WR_2_API get05-4Name info_sw_version +attr WR_2_API get05JSON . +attr WR_2_API get05Name 05_info_version +attr WR_2_API get05URL http://%IP-WR%/api/v1/info/version +attr WR_2_API get20-10Format %.2f +attr WR_2_API get20-10Name Statistic_EnergyChargeGrid_Month +attr WR_2_API get20-11Format %.2f +attr WR_2_API get20-11Name Statistic_EnergyChargeGrid_Total +attr WR_2_API get20-12Format %.2f +attr WR_2_API get20-12Name Statistic_EnergyChargeGrid_Year +attr WR_2_API get20-13Format %.2f +attr WR_2_API get20-13Name Statistic_EnergyChargeInvIn_Day +attr WR_2_API get20-14Format %.2f +attr WR_2_API get20-14Name Statistic_EnergyChargeInvIn_Month +attr WR_2_API get20-15Format %.2f +attr WR_2_API get20-15Name Statistic_EnergyChargeInvIn_Total +attr WR_2_API get20-16Format %.2f +attr WR_2_API get20-16Name Statistic_EnergyChargeInvIn_Year +attr WR_2_API get20-17Format %.2f +attr WR_2_API get20-17Name Statistic_EnergyChargePv_Day +attr WR_2_API get20-18Format %.2f +attr WR_2_API get20-18Name Statistic_EnergyChargePv_Month +attr WR_2_API get20-19Format %.2f +attr WR_2_API get20-19Name Statistic_EnergyChargePv_Total +attr WR_2_API get20-1Format %.2f +attr WR_2_API get20-1Name Statistic_Autarky_Day +attr WR_2_API get20-20Format %.2f +attr WR_2_API get20-20Name Statistic_EnergyChargePv_Year +attr WR_2_API get20-21Format %.2f +attr WR_2_API get20-21Name Statistic_EnergyDischarge_Day +attr WR_2_API get20-22Format %.2f +attr WR_2_API get20-22Name Statistic_EnergyDischarge_Month +attr WR_2_API get20-23Format %.2f +attr WR_2_API get20-23Name Statistic_EnergyDischarge_Total +attr WR_2_API get20-24Format %.2f +attr WR_2_API get20-24Name Statistic_EnergyDischarge_Year +attr WR_2_API get20-25Format %.2f +attr WR_2_API get20-25Name Statistic_EnergyDischargeGrid_Day +attr WR_2_API get20-26Format %.2f +attr WR_2_API get20-26Name Statistic_EnergyDischargeGrid_Month +attr WR_2_API get20-27Format %.2f +attr WR_2_API get20-27Name Statistic_EnergyDischargeGrid_Total +attr WR_2_API get20-28Format %.2f +attr WR_2_API get20-28Name Statistic_EnergyDischargeGrid_Year +attr WR_2_API get20-29Format %.2f +attr WR_2_API get20-29Name Statistic_EnergyHome_Day +attr WR_2_API get20-2Format %.2f +attr WR_2_API get20-2Name Statistic_Autarky_Month +attr WR_2_API get20-30Format %.2f +attr WR_2_API get20-30Name Statistic_EnergyHome_Month +attr WR_2_API get20-31Format %.2f +attr WR_2_API get20-31Name Statistic_EnergyHome_Total +attr WR_2_API get20-32Format %.2f +attr WR_2_API get20-32Name Statistic_EnergyHome_Year +attr WR_2_API get20-33Format %.2f +attr WR_2_API get20-33Name Statistic_EnergyHomeBat_Day +attr WR_2_API get20-34Format %.2f +attr WR_2_API get20-34Name Statistic_EnergyHomeBat_Month +attr WR_2_API get20-35Format %.2f +attr WR_2_API get20-35Name Statistic_EnergyHomeBat_Total +attr WR_2_API get20-36Format %.2f +attr WR_2_API get20-36Name Statistic_EnergyHomeBat_Year +attr WR_2_API get20-37Format %.2f +attr WR_2_API get20-37Name Statistic_EnergyHomeGrid_Day +attr WR_2_API get20-38Format %.2f +attr WR_2_API get20-38Name Statistic_EnergyHomeGrid_Month +attr WR_2_API get20-39Format %.2f +attr WR_2_API get20-39Name Statistic_EnergyHomeGrid_Total +attr WR_2_API get20-3Format %.2f +attr WR_2_API get20-3Name Statistic_Autarky_Total +attr WR_2_API get20-40Format %.2f +attr WR_2_API get20-40Name Statistic_EnergyHomeGrid_Year +attr WR_2_API get20-41Format %.2f +attr WR_2_API get20-41Name Statistic_EnergyHomeOwn_Total +attr WR_2_API get20-42Format %.2f +attr WR_2_API get20-42Name Statistic_EnergyHomePv_Day +attr WR_2_API get20-43Format %.2f +attr WR_2_API get20-43Name Statistic_EnergyHomePv_Month +attr WR_2_API get20-44Format %.2f +attr WR_2_API get20-44Name Statistic_EnergyHomePv_Total +attr WR_2_API get20-45Format %.2f +attr WR_2_API get20-45Name Statistic_EnergyHomePv_Year +attr WR_2_API get20-46Format %.2f +attr WR_2_API get20-46Name Statistic_EnergyPv1_Day +attr WR_2_API get20-47Format %.2f +attr WR_2_API get20-47Name Statistic_EnergyPv1_Month +attr WR_2_API get20-48Format %.2f +attr WR_2_API get20-48Name Statistic_EnergyPv1_Total +attr WR_2_API get20-49Format %.2f +attr WR_2_API get20-49Name Statistic_EnergyPv1_Year +attr WR_2_API get20-4Format %.2f +attr WR_2_API get20-4Name Statistic_Autarky_Year +attr WR_2_API get20-50Format %.2f +attr WR_2_API get20-50Name Statistic_EnergyPv2_Day +attr WR_2_API get20-51Format %.2f +attr WR_2_API get20-51Name Statistic_EnergyPv2_Month +attr WR_2_API get20-52Format %.2f +attr WR_2_API get20-52Name Statistic_EnergyPv2_Total +attr WR_2_API get20-53Format %.2f +attr WR_2_API get20-53Name Statistic_EnergyPv2_Year +attr WR_2_API get20-54Format %.2f +attr WR_2_API get20-54Name Statistic_EnergyPv3_Day +attr WR_2_API get20-55Format %.2f +attr WR_2_API get20-55Name Statistic_EnergyPv3_Month +attr WR_2_API get20-56Format %.2f +attr WR_2_API get20-56Name Statistic_EnergyPv3_Total +attr WR_2_API get20-57Format %.2f +attr WR_2_API get20-57Name Statistic_EnergyPv3_Year +attr WR_2_API get20-58Format %.2f +attr WR_2_API get20-58Name Statistic_OwnConsumptionRate_Day +attr WR_2_API get20-59Format %.2f +attr WR_2_API get20-59Name Statistic_OwnConsumptionRate_Month +attr WR_2_API get20-5Format %.2f +attr WR_2_API get20-5Name Statistic_CO2Saving_Day +attr WR_2_API get20-60Format %.2f +attr WR_2_API get20-60Name Statistic_OwnConsumptionRate_Total +attr WR_2_API get20-61Format %.2f +attr WR_2_API get20-61Name Statistic_OwnConsumptionRate_Year +attr WR_2_API get20-62Format %.2f +attr WR_2_API get20-62Name Statistic_Yield_Day +attr WR_2_API get20-63Format %.2f +attr WR_2_API get20-63Name Statistic_Yield_Month +attr WR_2_API get20-64Format %.2f +attr WR_2_API get20-64Name Statistic_Yield_Total +attr WR_2_API get20-65Format %.2f +attr WR_2_API get20-65Name Statistic_Yield_Year +attr WR_2_API get20-6Format %.2f +attr WR_2_API get20-6Name Statistic_CO2Saving_Month +attr WR_2_API get20-7Format %.2f +attr WR_2_API get20-7Name Statistic_CO2Saving_Total +attr WR_2_API get20-8Format %.2f +attr WR_2_API get20-8Name Statistic_CO2Saving_Year +attr WR_2_API get20-9Format %.2f +attr WR_2_API get20-9Name Statistic_EnergyChargeGrid_Day +attr WR_2_API get20Header authorization: Session %auth_sessionId% +attr WR_2_API get20JSON 01_processdata_.._value +attr WR_2_API get20Name 20_Statistic_EnergyFlow +attr WR_2_API get20URL http://%IP-WR%/api/v1/processdata/scb:statistic:EnergyFlow +attr WR_2_API get40Header01 authorization: Session %auth_sessionId% +attr WR_2_API get40Header02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_2_API get40Name 40_Generator_ShadowMgmt +attr WR_2_API get40URL http://%IP-WR%/api/v1/settings/devices:local/Generator:ShadowMgmt:Enable +attr WR_2_API get59Data {"end":"%end_date%","begin":"%begin_date%"} +attr WR_2_API get59Header01 authorization: Session %auth_sessionId% +attr WR_2_API get59Header02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_2_API get59Name 59_logdata_download +attr WR_2_API get59URL http://%IP-WR%/api/v1/logdata/download +attr WR_2_API get60Header authorization: Session %auth_sessionId% +attr WR_2_API get60Name 60_update_status +attr WR_2_API get60URL http://%IP-WR%/api/v1/update/status +attr WR_2_API getHeader01 Accept-Encoding: gzip,deflate +attr WR_2_API getHeader02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_2_API group PV Eigenverbrauch +attr WR_2_API icon sani_solar +attr WR_2_API reAuthRegex "authenticated":false|"processdata":\[\]|wrong credentials|Not authorized +attr WR_2_API reading0101JSON nonce +attr WR_2_API reading0101Name auth_nonce +attr WR_2_API reading0102JSON rounds +attr WR_2_API reading0102Name auth_rounds +attr WR_2_API reading0103JSON salt +attr WR_2_API reading0103Name auth_salt +attr WR_2_API reading0104JSON transactionId +attr WR_2_API reading0104Name auth_transactionId +attr WR_2_API reading0201JSON signature +attr WR_2_API reading0201Name auth_signature +attr WR_2_API reading0202JSON token +attr WR_2_API reading0202Name auth_token +attr WR_2_API reading0301JSON message +attr WR_2_API reading0301Name info_message +attr WR_2_API reading0302JSON error +attr WR_2_API reading0302Name info_error +attr WR_2_API reading03JSON sessionId +attr WR_2_API reading03Name auth_sessionId +attr WR_2_API reading40Name Generator_ShadowMgmt +attr WR_2_API reading40Regex Generator:ShadowMgmt.*value":"(\d+) +attr WR_2_API replacement01Mode text +attr WR_2_API replacement01Regex %IP-WR% +attr WR_2_API replacement01Value 192.168.178.19 +attr WR_2_API replacement02Mode expression +attr WR_2_API replacement02Regex %START% +attr WR_2_API replacement02Value {my $NAME="WR_2_API";; plenticore_auth("start","user","$NAME")} +attr WR_2_API replacement04Mode expression +attr WR_2_API replacement04Regex %FINISH% +attr WR_2_API replacement04Value {my $NAME="WR_2_API";; plenticore_auth("finish","user","$NAME",ReadingsVal("$NAME","auth_randomString64","missed"),ReadingsVal("$NAME","auth_nonce","missed"),ReadingsVal("$NAME","auth_salt","missed"),ReadingsVal("$NAME","auth_rounds","missed"),ReadingsVal("$NAME","auth_transactionId","missed"))} +attr WR_2_API replacement05Mode expression +attr WR_2_API replacement05Regex %SESSION% +attr WR_2_API replacement05Value {my $NAME="WR_2_API";; plenticore_auth("session","user","$NAME",ReadingsVal("$NAME","auth_randomString64","missed"),ReadingsVal("$NAME","auth_nonce","missed"),ReadingsVal("$NAME","auth_salt","missed"),ReadingsVal("$NAME","auth_rounds","missed"),ReadingsVal("$NAME","auth_transactionId","missed"),ReadingsVal("$NAME","auth_token","missed"))} +attr WR_2_API replacement06Mode reading +attr WR_2_API replacement06Regex %auth_signature% +attr WR_2_API replacement06Value auth_signature +attr WR_2_API replacement07Mode reading +attr WR_2_API replacement07Regex %auth_sessionId% +attr WR_2_API replacement07Value auth_sessionId +attr WR_2_API replacement08Mode expression +attr WR_2_API replacement08Regex %begin_date% +attr WR_2_API replacement08Value {POSIX::strftime("%Y-%m-%d",localtime(time))} +attr WR_2_API replacement09Mode expression +attr WR_2_API replacement09Regex %end_date% +attr WR_2_API replacement09Value {POSIX::strftime("%Y-%m-%d",localtime(time))} +attr WR_2_API room Strom->Photovoltaik +attr WR_2_API set06Header01 authorization: Session %auth_sessionId% +attr WR_2_API set06Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_2_API set06Method POST +attr WR_2_API set06Name 06_auth_logout +attr WR_2_API set06NoArg 1 +attr WR_2_API set06URL http://%IP-WR%/api/v1/auth/logout +attr WR_2_API set4002Data [{"moduleid":"devices:local","settings":[{"id":"Generator:ShadowMgmt:Enable","value":"$val"}]}] +attr WR_2_API set4002FollowGet 40_Generator_ShadowMgmt +attr WR_2_API set4002Header01 authorization: Session %auth_sessionId% +attr WR_2_API set4002Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_2_API set4002Hint slider,0,1,3 +attr WR_2_API set4002Method PUT +attr WR_2_API set4002Name 40_02_Generator_ShadowMgmt +attr WR_2_API set4002URL http://%IP-WR%/api/v1/settings +attr WR_2_API set4101Data [{"moduleid":"devices:local","settings":[{"id":"DigitalOutputs:Customer:ConfigurationFlags","value":"$val"},{"id":"DigitalOutputs:Customer:DelayTime","value":"5"},{"id":"DigitalOutputs:Customer:PowerMode:OnPowerThreshold","value":"100000"},{"id":"DigitalOutputs:Customer:TimeMode:MaxNoOfSwitchingCyclesPerDay","value":"24"},{"id":"DigitalOutputs:Customer:TimeMode:PowerThreshold","value":"1"},{"id":"DigitalOutputs:Customer:TimeMode:RunTime","value":"1440"},{"id":"DigitalOutputs:Customer:TimeMode:StableTime","value":"1"}]}] +attr WR_2_API set4101FollowGet 41_DigitalOutputs +attr WR_2_API set4101Header01 authorization: Session %auth_sessionId% +attr WR_2_API set4101Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_2_API set4101Hint 0,9,13,14 +attr WR_2_API set4101Method PUT +attr WR_2_API set4101Name 41_01_DigitalOutputs +attr WR_2_API set4101URL http://%IP-WR%/api/v1/settings +attr WR_2_API set50-10Name Event_02_code +attr WR_2_API set50-11Name Event_02_description +attr WR_2_API set50-12Name Event_02_end_time +attr WR_2_API set50-13Name Event_02_group +attr WR_2_API set50-14Name Event_02_is_active +attr WR_2_API set50-15Name Event_02_long_description +attr WR_2_API set50-16Name Event_02_start_time +attr WR_2_API set50-17Name Event_03_category +attr WR_2_API set50-18Name Event_03_code +attr WR_2_API set50-19Name Event_03_description +attr WR_2_API set50-1Name Event_01_category +attr WR_2_API set50-20Name Event_03_end_time +attr WR_2_API set50-21Name Event_03_group +attr WR_2_API set50-22Name Event_03_is_active +attr WR_2_API set50-23Name Event_03_long_description +attr WR_2_API set50-24Name Event_03_start_time +attr WR_2_API set50-25Name Event_04_category +attr WR_2_API set50-26Name Event_04_code +attr WR_2_API set50-27Name Event_04_description +attr WR_2_API set50-28Name Event_04_end_time +attr WR_2_API set50-29Name Event_04_group +attr WR_2_API set50-2Name Event_01_code +attr WR_2_API set50-30Name Event_04_is_active +attr WR_2_API set50-31Name Event_04_long_description +attr WR_2_API set50-32Name Event_04_start_time +attr WR_2_API set50-33Name Event_05_category +attr WR_2_API set50-34Name Event_05_code +attr WR_2_API set50-35Name Event_05_description +attr WR_2_API set50-36Name Event_05_end_time +attr WR_2_API set50-37Name Event_05_group +attr WR_2_API set50-38Name Event_05_is_active +attr WR_2_API set50-39Name Event_05_long_description +attr WR_2_API set50-3Name Event_01_description +attr WR_2_API set50-40Name Event_05_start_time +attr WR_2_API set50-4Name Event_01_end_time +attr WR_2_API set50-5Name Event_01_group +attr WR_2_API set50-6Name Event_01_is_active +attr WR_2_API set50-7Name Event_01_long_description +attr WR_2_API set50-8Name Event_01_start_time +attr WR_2_API set50-9Name Event_02_category +attr WR_2_API set50Data {"max":5,"language":"$val"} +attr WR_2_API set50Header01 authorization: Session %auth_sessionId% +attr WR_2_API set50Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_2_API set50Hint en-gb,de-de +attr WR_2_API set50JSON . +attr WR_2_API set50Name 50_events_latest_5 +attr WR_2_API set50ParseResponse 1 +attr WR_2_API set50TextArg 1 +attr WR_2_API set50URL http://%IP-WR%/api/v1/events/latest +attr WR_2_API set6001Header01 authorization: Session %auth_sessionId% +attr WR_2_API set6001Header02 Content-type:application/json, Accept:application/json, Connection:keep-alive +attr WR_2_API set6001Method POST +attr WR_2_API set6001Name 60_01_Reset_Wechselrichter +attr WR_2_API set6001NoArg 1 +attr WR_2_API set6001URL http://%IP-WR%/api/v1/system/reboot +attr WR_2_API showBody 1 +attr WR_2_API showError 1 +attr WR_2_API sid01Data %START% +attr WR_2_API sid01ParseResponse 1 +attr WR_2_API sid01URL http://%IP-WR%/api/v1/auth/start +attr WR_2_API sid02Data %FINISH% +attr WR_2_API sid02ParseResponse 1 +attr WR_2_API sid02URL http://%IP-WR%/api/v1/auth/finish +attr WR_2_API sid03Data %SESSION% +attr WR_2_API sid03ParseResponse 1 +attr WR_2_API sid03URL http://%IP-WR%/api/v1/auth/create_session +attr WR_2_API sidHeader01 Accept-Encoding: gzip,deflate +attr WR_2_API sidHeader02 Content-type: application/json, Accept: application/json, Connection: keep-alive +attr WR_2_API sortby 212 +attr WR_2_API timeout 7 +attr WR_2_API verbose 0 \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_3_Fake_WR.txt b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_3_Fake_WR.txt new file mode 100644 index 000000000..b63f766a5 --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_3_Fake_WR.txt @@ -0,0 +1,49 @@ +defmod WR_3 ModbusAttr 71 slave 192.168.178.40:1502 TCP +attr WR_3 DbLogExclude .* +attr WR_3 comment Version 2022.10.27 09:00\ +Fremder WR am KSEM +attr WR_3 dev-h-combine 20 +attr WR_3 dev-h-defFormat %.2f +attr WR_3 dev-h-defLen 2 +attr WR_3 dev-h-defRevRegs 1 +attr WR_3 dev-h-defUnpack f> +attr WR_3 dev-type-STR-format %s +attr WR_3 dev-type-STR-len 8 +attr WR_3 dev-type-STR-revRegs 0 +attr WR_3 dev-type-STR-unpack a* +attr WR_3 disable 1 +attr WR_3 group PV Eigenverbrauch +attr WR_3 icon sani_solar +attr WR_3 obj-h1066-reading Total_DC_P_sumOfAllPVInputs +attr WR_3 obj-h14-reading Inverter_serial_number +attr WR_3 obj-h14-type STR +attr WR_3 obj-h154-reading I_L1 +attr WR_3 obj-h156-reading Active_P_L1 +attr WR_3 obj-h158-reading U_L1 +attr WR_3 obj-h160-reading I_L2 +attr WR_3 obj-h162-reading Active_P_L2 +attr WR_3 obj-h164-reading U_L2 +attr WR_3 obj-h166-reading I_L3 +attr WR_3 obj-h168-reading Active_P_L3 +attr WR_3 obj-h170-reading U_L3 +attr WR_3 obj-h172-reading Total_AC_Active_P +attr WR_3 obj-h172-set 1 +attr WR_3 obj-h38-reading Software-Version_Maincontroller_MC +attr WR_3 obj-h38-type STR +attr WR_3 obj-h46-reading Software-Version_IO-Controller_IOC +attr WR_3 obj-h46-type STR +attr WR_3 obj-h514-len 1 +attr WR_3 obj-h514-reading Battery_Actual_SOC +attr WR_3 obj-h56-format %.0f +attr WR_3 obj-h56-reading Inverter_state +attr WR_3 obj-h56-unpack N +attr WR_3 obj-h582-reading Actual_Battery_charge-discharge_P +attr WR_3 obj-h6-reading Inverter_Article_number +attr WR_3 obj-h6-type STR +attr WR_3 obj-h768-len 32 +attr WR_3 obj-h768-reading Productname +attr WR_3 obj-h768-type STR +attr WR_3 propagateVerbose 1 +attr WR_3 room Strom->Photovoltaik +attr WR_3 sortby 311 +attr WR_3 verbose 0 diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_ctl.txt b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_ctl.txt new file mode 100644 index 000000000..dc8d6a18d --- /dev/null +++ b/fhem/contrib/ch.eick/Photovoltaik/Wechselrichter/RAW_WR_ctl.txt @@ -0,0 +1,495 @@ +defmod WR_ctl DOIF ################################################################################################################\ +## 1 Scheduling für das Abholen der Wechselrichter Statistiken\ +## Umschaltung des Schattenmanagements\ +##\ +20_Statistic_EnergyFlow\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ( [:57] ## Kurz vor jeder vollen Stunde\ + )\ + or [$SELF:ui_command_2] eq "20_Statistic_EnergyFlow" ## Hier wird das uiTable select ausgewertet\ + ) {\ +\ + ::CommandGet(undef, "WR_2_API 20_Statistic_EnergyFlow");; ## Zuerst WR_2 und anschließend\ + set_Exec("wait_Statistic",2,'::CommandGet(undef, "WR_1_API 20_Statistic_EnergyFlow")');; ## WR_1, damit die Schwarm Werte stimmen\ +\ + ## Schattenmanagement \ + if ($hour == 9) {\ + ::CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 0");; ## Komplett aus\ + }\ + if ($hour == 16) {\ + ::CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 2");; ## Im Westen unten einschalten\ + }\ + if ($hour == 21) {\ + ::CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 1");; ## Schattenmanagement für den Osten vorbereiten\ + }\ +\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF cmd_1 : Abfrage der Statistiken";;\ + }\ +\ + set_Reading("ui_command_2","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 2 Start der KI Prognose\ +## Der Reading Name und das Device werden in LogDBRep_PV_KI_Prognose im executeAfterProc eingestellt\ +## "/opt/fhem/python/bin/PV_KI_Prognose.py 192.168.178.40 192.168.178.40 LogDBRep_PV_KI_Prognose WR_1_ctl Yield_fc"\ +##\ +2_KI_Prognose\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ReadingsVal("LogDBRep_PV_KI_Prognose","PV_KI_Prognose","null") eq "done" ## Die Prognose darf nicht gerade laufen !!!\ + and\ + (\ + ([05:00-22:00] and [:03] ## In der PV-Zeit jede Stunde aktualisieren\ + )\ + or [$SELF:ui_command_1] eq "2_KI_Prognose" ## Hier wird das uiTable select ausgewertet\ + )\ + ) {\ +\ + ::CommandSet(undef, "LogDBRep_PV_KI_Prognose sqlCmd call dwd_load(curdate(),'none')");;\ +\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 2_KI_Prognose : Start KI Prognose";;\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 2 Erstellen des Diagramms im uiTable\ +3_WR_ctl_Diagramm\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and [$SELF:Yield_fc0_06] ## Wenn die Prognose aktualisiert wurde\ + or [$SELF:ui_command_1] eq "3_WR_ctl_Diagramm" ## Hier wird das uiTable select ausgewertet\ + ) {\ +\ + my (@out) = ("") x 2;; ## Es wird für jedes Diagramm ein Array benötigt\ + my $timestamp;;\ +\ + for (my $j=0;;$j<=1;;$j++){ ## loop fc0 und fc1\ + for (my $i=5;;$i<=21;;$i++){ ## loop für die PV-Zeit\ + $timestamp = sprintf("%s_%02d:00:00", POSIX::strftime("%Y-%m-%d",localtime(time)), $i);;\ + $out[$j] .= $timestamp." ".::round(::ReadingsVal("$SELF",sprintf("Yield_fc%d_%02d",$j, $i),0)/1000,2)."\n";;\ + } # End $i\ + } # End $j\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 3_WR_ctl_Diagramm : Werte für das Diagramm";;\ + print($out[0]."\n\n");;\ + print($out[1]."\n");;\ + }\ + ## Yield_fc*_current dient nur als Trigger für die card Diagramme, damit diese im uiTable aktualisiert werden.\ + ::DOIF_modify_card_data("$SELF","$SELF","Yield_fc0_current","bar1day",0,$out[0]);; ## Der fc1 wird verschoben, da card nicht\ + ::DOIF_modify_card_data("$SELF","$SELF","Yield_fc1_current","bar1day",-86400,$out[1]);; ## den nächsten Tag anzeigen kann\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 4 WR_1_API setzen der init Werte für die Berechnung des Hausverbrauches. Bei Fehlern in der Verbrauchsanzeige\ +## muss man die ersten Werte des Tages gegen 00:01 aus der DB setzen. \ +4_WR_1_API_init_Werte\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + [00:01]\ + or [$SELF:ui_command_2] eq "4_WR_1_API_init_Werte" ## Hier wird das uiTable select ausgewertet\ + ) {\ + if ($hour > 0) {\ + ## Achtung, der init Wert muss auf den ersten Wert des Tages korrigiert werden, dieser ist in der DB\ +\ + ## Korrektur der Tages Werte\ + my $Active_energy = ::CommandGet(undef, "LogDBRep_$SELF_SQL sqlCmdBlocking\ + SELECT VALUE FROM history\ + WHERE DEVICE='WR_0_KSEM'\ + AND READING='Active_energy-'\ + AND TIMESTAMP > curdate() - interval 1 month\ + AND TIMESTAMP <= concat(curdate(),' 00:01')\ + ORDER BY TIMESTAMP desc\ + LIMIT 1;;") ;;\ + fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Day $Active_energy");;\ +\ + $Active_energy = ::CommandGet(undef, "LogDBRep_$SELF_SQL sqlCmdBlocking\ + SELECT VALUE FROM history\ + WHERE DEVICE='WR_0_KSEM'\ + AND READING='Active_energy+'\ + AND TIMESTAMP > curdate() - interval 1 month\ + AND TIMESTAMP <= concat(curdate(),' 00:01')\ + ORDER BY TIMESTAMP desc\ + LIMIT 1;;") ;;\ + fhem("setreading WR_1_API SW_Meter_init_Grid_Day $Active_energy");;\ +\ + ## Korrektur der Monats Werte\ + $Active_energy = ::CommandGet(undef, "LogDBRep_$SELF_SQL sqlCmdBlocking\ + SELECT VALUE FROM history\ + WHERE DEVICE='WR_0_KSEM'\ + AND READING='Active_energy-'\ + AND TIMESTAMP > curdate() - interval 1 month\ + AND TIMESTAMP <= subdate(curdate(), (day(curdate())-1))\ + ORDER BY TIMESTAMP desc\ + LIMIT 1;;") ;;\ + fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Month $Active_energy");;\ +\ + $Active_energy = ::CommandGet(undef, "LogDBRep_$SELF_SQL sqlCmdBlocking\ + SELECT VALUE FROM history\ + WHERE DEVICE='WR_0_KSEM'\ + AND READING='Active_energy+'\ + AND TIMESTAMP > curdate() - interval 1 month\ + AND TIMESTAMP <= LAST_DAY(SUBDATE(curdate(), INTERVAL 1 MONTH))\ + ORDER BY TIMESTAMP desc\ + LIMIT 1;;") ;;\ + fhem("setreading WR_1_API SW_Meter_init_Grid_Month $Active_energy");;\ +\ + ::CommandGet(undef, "WR_2_API 20_Statistic_EnergyFlow");; ## Zuerst WR_2 und anschließend\ + ::CommandGet(undef, "WR_1_API 20_Statistic_EnergyFlow");; ## WR_1, damit die Schwarm Werte stimmen\ +\ + } else {\ + fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Day ".[?WR_0_KSEM:Active_energy-]);;\ + fhem("setreading WR_1_API SW_Meter_init_Grid_Day ".[?WR_0_KSEM:Active_energy+]);;\ + }\ +\ + if ($mday eq 1) {\ + fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Month ".[?WR_0_KSEM:Active_energy-]);;\ + fhem("setreading WR_1_API SW_Meter_init_Grid_Month ".[?WR_0_KSEM:Active_energy+]);;\ +\ + if ($yday eq 0) {\ + fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Year ".[?WR_0_KSEM:Active_energy-]);;\ + fhem("setreading WR_1_API SW_Meter_init_Grid_Year ".[?WR_0_KSEM:Active_energy+]);;\ + }\ + }\ +\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 4_WR_1_API_init_Werte : init Werte gesetzt";;\ + }\ +\ + set_Reading("ui_command_2","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ + +attr WR_ctl DbLogExclude .* +attr WR_ctl DbLogInclude Yield_fc0_day,Yield_fc0_middayhigh.* +attr WR_ctl comment Version 2023.06.21 12:00 \ +\ +Die readings Yield_fc* werden direkt vom KI Prognose Skript in die Datenbank geschrieben und müssen hier nicht extra gelogged werden. +attr WR_ctl disable 0 +attr WR_ctl group PV Eigenverbrauch +attr WR_ctl icon sani_solar +attr WR_ctl room 2_PV_Steuerung,Strom->Photovoltaik +attr WR_ctl sortby 11 +attr WR_ctl uiState {\ +package ui_Table;;\ + $TABLE = "style='width:100%;;'";;\ +\ + $TD{0..6}{0} = "style='border-top-style:solid;;border-bottom-style:solid;;border-left-style:solid;;border-left-width:2px;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ + $TD{0..6}{1..4} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ + $TD{0..6}{5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ +\ +}\ +\ +"KI Prognose Kommando Auswahl
Mittags Limit Inverter_Max_Power / KI Status
"|\ +widget([$SELF:ui_command_1],"uzsuDropDown,---,2_KI_Prognose,3_WR_ctl_Diagramm") |\ +""|\ +""|\ +"MySQL ".[LogDBRep_PV_KI_Prognose:state]."
KI ".([LogDBRep_PV_KI_Prognose:state] ne "done") ? "waiting" : [LogDBRep_PV_KI_Prognose:PV_KI_Prognose]\ +\ +"Statistiken"|\ +Yield(0)|\ +Yield('Tag')|\ +Yield('4h')|\ +Yield('Rest')\ +\ +card([$SELF:Yield_fc0_current:bar1day],undef,undef,0,17,90,0,"fc0 kWh",undef,"2","130,,,,,,220").card([$SELF:Yield_fc1_current:bar1day],undef,undef,0,17,90,0,"fc1 kWh",undef,"2","130,,,,,,220")|\ +"nächste 3h

".Yield(1)."
".Yield(2)."
".Yield(3)|\ +"Vor- / Nachmittag

".Yield('Vormittag')."
".Yield('Nachmittag')|\ +"Maximum


".Yield("max")."
".Yield("max_time")|\ +"Mittagshoch


fc0 ".[$SELF:Yield_fc0_middayhigh_start]." - ".[$SELF:Yield_fc0_middayhigh_stop]."
fc1 ".[$SELF:Yield_fc1_middayhigh_start]." - ".[$SELF:Yield_fc1_middayhigh_stop]\ +\ +"WR_1 / KSEM
/ PV Reserve / Netz Leistung
"|\ +""|\ +sprintf("%d W",[WR_1:SW_Total_PV_P_reserve])|\ +(::ReadingsVal("WR_1","Total_Active_P_EM",0) < -10) ? "Einspeisen" : (::ReadingsVal("WR_1","Total_Active_P_EM",0) > 15)? "Netzbezug" : "Standby"|\ +sprintf("%d W",[WR_1:Total_Active_P_EM])\ +\ +"Ertrag aktuell
/ Tag / Monat / Jahr
"|\ +""|\ +sprintf("%d kWh",::round([WR_1:SW_Yield_Daily]/1000 ,0))|\ +sprintf("%d kWh",::round([WR_1:SW_Yield_Monthly]/1000 ,0))|\ +sprintf("%d kWh",::round([WR_1:SW_Yield_Yearly]/1000 ,0))\ +\ +"Speicher
Temperatur / nutzbare Ladung / Status / Leistung / akt. SOC
"|\ +(::ReadingsVal("WR_1_API","DigitalOutputs_ConfigurationFlags",0) == 9) ? "Lüfter An
" : "
".sprintf("%.1f °C",::ReadingsVal("WR_1","Battery_temperature",0))|\ +sprintf("%d Wh",::ReadingsVal("WR_1","Actual_Battery_charge_usable_P",0))|\ +Status_Speicher()|\ +[WR_1:Actual_Battery_charge_-minus_or_discharge_-plus_P]." W
".sprintf("%d %%",[WR_1:Act_state_of_charge])\ +\ +"WR_1_API
Kommando Auswahl
"|\ +widget([$SELF:ui_command_2],"uzsuDropDown,---,20_Statistic_EnergyFlow,4_WR_1_API_init_Werte") |\ +""|\ +""|\ +"" +attr WR_ctl uiTable {\ +package ui_Table;;\ + $TABLE = "style='width:100%;;'";;\ +\ + $TD{0..18}{0} = "style='border-top-style:solid;;border-bottom-style:solid;;border-left-style:solid;;border-left-width:2px;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ + $TD{0..18}{1..5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ + $TD{0..18}{6} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ +\ +sub FUNC_Status {\ + my($value, $min, $colorMin, $statusMin, $colorMiddel, $statusMiddle, $max, $colorMax, $statusMax)=@_;;\ + my $ret = ($value < $min)? ''.$statusMin.'' : ($value > $max)? ''.$statusMax.'' : ''.$statusMiddle.'';;\ + return $ret;;\ + }\ +\ +sub Status_Speicher {\ + if (::ReadingsVal("WR_1","Actual_Battery_charge_-minus_or_discharge_-plus_P",0) < -10) {\ + return "Laden
".::ReadingsVal("WR_1","State_of_EM","n/a")\ + } elsif (::ReadingsVal("WR_1","Actual_Battery_charge_-minus_or_discharge_-plus_P",0) > 15) {\ + return "Entladen
".::ReadingsVal("WR_1","State_of_EM","n/a")\ + } else {\ + return "Standby"."
".::ReadingsVal("WR_1","State_of_EM","n/a")\ + }\ +}\ +sub Yield {\ + my($i)=@_;;\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;;\ +\ + if ($i eq "4h") {\ + return sprintf("%05d 4h",::ReadingsVal("$SELF","Yield_fc0_4h",0));;\ + } elsif ($i eq "Tag") {\ + return sprintf("%05d Tag",::ReadingsVal("$SELF","Yield_fc0_day",0));;\ + } elsif ($i eq "Rest") {\ + return sprintf("%05d Rest",::ReadingsVal("$SELF","Yield_fc0_rest",0));;\ + } elsif ($i eq "max") {\ + return sprintf("%05d Wh",::ReadingsVal("$SELF","Yield_fc0_max",0));;\ + } elsif ($i eq "max_time") {\ + return ::ReadingsVal("$SELF","Yield_fc0_max_time","null");;\ + } elsif ($i eq "Vormittag") {\ + return sprintf("%05d Wh",::ReadingsVal("$SELF","Yield_fc0_morning",0));;\ + } elsif ($i eq "Nachmittag") {\ + return sprintf("%05d Wh",::ReadingsVal("$SELF","Yield_fc0_afternoon",0));;\ + }\ + my $j = $i + $hour;;\ + if ($j > 23) {\ + if ($j == 24) {$j = 0}\ + elsif ($j == 25) {$j = 1}\ + elsif ($j == 26) {$j = 2}\ + }\ + return sprintf("%02d : %05d Wh",$j,::ReadingsVal("$SELF","Yield_fc0_".sprintf("%02d",$j),0));;\ + }\ +\ +sub WR_ctl_Format {\ + my($period,$device,$reading)=@_;;\ + my $value = 0;;\ +\ + my $DayBefore = "LogDBRep_Statistic_previous_Day";;\ + my $DayPrevious = ::ReadingsTimestamp("$DayBefore",$device."_".$reading."_Day","null");;\ + $DayPrevious = ($DayPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp("$DayBefore",$device."_".$reading."_Day","null")))) : "null";;\ +\ + if ($period eq "_Dx") {\ + if ($DayPrevious ne "null") {\ + return " / gestern";;\ + }\ + }\ +\ + my $MonthBefore = "LogDBRep_Statistic_previous_Month";;\ + my $MonthPrevious = ::ReadingsTimestamp("$MonthBefore",$device."_".$reading."_Month","null");;\ + $MonthPrevious = ($MonthPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp("$MonthBefore",$device."_".$reading."_Month","null")))) : "null";;\ +\ + if ($period eq "_Mx") {\ + if ($MonthPrevious ne "null") {\ + return " / Vormonat";;\ + }\ + }\ +\ + my $QuarterBefore = "LogDBRep_Statistic_previous_Quarter";;\ + my $QuarterPrevious = "null";;\ + if ($period eq "_Qx" or $period eq "_Quarter" or $period eq "time_Quarter") {\ + foreach my $loop (1,2,3,4) {\ + if (::ReadingsVal("$QuarterBefore","Q".$loop,0) eq "previous") { \ + $QuarterPrevious = "Q".$loop \ + }\ + }\ + if ($period eq "_Qx") {\ + return $QuarterPrevious;;\ + }\ + }\ +\ + my $YearBefore = "LogDBRep_Statistic_previous_Year";;\ + my $YearPrevious = ::ReadingsTimestamp($YearBefore,$reading."_Year","null");;\ + $YearPrevious = ($YearPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp("$YearBefore",$reading."_Year","null")))) : "null";;\ +\ + if ($period eq "_Yx") {\ + if ($YearPrevious ne "null") {\ + return " / Vorjahr";;\ + }\ + }\ +\ + if ($period eq "_Year") {\ + $YearPrevious = ::ReadingsTimestamp($YearBefore,$reading.$period,"null");;\ + $YearPrevious = ($YearPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp($YearBefore,$reading.$period,"null")))) : "null";;\ + }\ +\ + if ($period eq "actual" and $reading eq "Autarky") {\ + my $valA = ::ReadingsVal($device, "SW_Total_AC_Active_P",0) - ::ReadingsVal($device, "SW_Home_own_consumption_from_grid",0);;\ + my $calcVal = ($valA > 0) ? ::round($valA /($valA + ::ReadingsVal($device, "SW_Home_own_consumption_from_grid",0))*100 ,0) : 0;;\ + return sprintf("%3d %%",(($calcVal > 100) ? 100 : $calcVal) );;\ + }\ +\ + if ($period eq "actual" and $reading eq "OwnConsumptionRate") {\ + my $valS = ::ReadingsVal($device,"SW_Total_AC_Active_P",0);;\ + my $calcVal = ($valS > 0) ? ::round((::ReadingsVal($device,"SW_Home_own_consumption_from_PV",0) +\ + ::ReadingsVal($device,"SW_Home_own_consumption_from_Battery",0)) / $valS * 100 ,0) : 0;;\ + return sprintf("%3d %%",(($calcVal > 100) ? 100 : $calcVal) );;\ + }\ +\ + if ($period eq "time_Day" and $reading eq "SW_Statistic_Autarky") {\ + return POSIX::strftime("%H:%M",localtime(::time_str2num(::ReadingsTimestamp($device, $reading."_Day",0))))\ + }\ +\ + if ($period eq "time_Month" and $reading eq "SW_Statistic_Autarky") {\ + return POSIX::strftime("%H:%M",localtime(::time_str2num(::ReadingsTimestamp($device, $reading."_Month",0))));;\ + }\ +\ + if ($period eq "time_Quarter") {\ + if ($QuarterPrevious ne "null") {\ + return POSIX::strftime("%Y-%m-%d",localtime(::time_str2num(::ReadingsTimestamp($QuarterBefore, $QuarterPrevious,0))));;\ + }\ + }\ +\ + if ($period eq "time_Year" and $reading eq "SW_Statistic_Autarky") {\ + my $cy = POSIX::strftime("%H:%M",localtime(::time_str2num(::ReadingsTimestamp($device, $reading."_Year",0))));;\ + $cy .= ($YearPrevious ne "null") ? " / ".$YearPrevious : "";;\ + return $cy;;\ + }\ +\ + if ($period eq "Autarky_Year" or $period eq "OwnConsumptionRate_Year") {\ + $value = sprintf("%3d %%",::ReadingsVal($device,$reading."_Year",0));;\ + $value .= ($YearPrevious ne "null") ? sprintf(" / %3d %%", ::ReadingsVal($YearBefore,$reading."_Year",0) ) : "";;\ + return $value;;\ + } elsif ($period eq "_Day") {\ + if ($reading eq "SW_Statistic_Autarky" or $reading eq "SW_Statistic_OwnConsumptionRate") {\ + $value = sprintf("%3d %%",::ReadingsVal($device,$reading.$period,0) );;\ + $value .= ($DayPrevious ne "null") ? sprintf(" / %3d %%", ::ReadingsVal($DayBefore,$device."_".$reading.$period,0) ) : "";;\ + } else {\ + $value = sprintf("%04d",::ReadingsVal($device,$reading.$period,0)/1000);;\ + $value .= ($DayPrevious ne "null") ? sprintf(" / %04d", ::ReadingsVal($DayBefore,$device."_".$reading.$period,0) ) : "";;\ + }\ + return $value;;\ + } elsif ($period eq "_Month") {\ + if ($reading eq "SW_Statistic_Autarky" or $reading eq "SW_Statistic_OwnConsumptionRate") {\ + $value = sprintf("%3d %%",::ReadingsVal($device,$reading.$period,0) );;\ + $value .= ($MonthPrevious ne "null") ? sprintf(" / %3d %%", ::ReadingsVal($MonthBefore,$device."_".$reading.$period,0) ) : "";;\ + } else {\ + $value = sprintf("%04d",::ReadingsVal($device,$reading.$period,0)/1000);;\ + $value .= ($MonthPrevious ne "null") ? sprintf(" / %04d", ::ReadingsVal($MonthBefore,$device."_".$reading.$period,0) ) : "";;\ + }\ + return $value;;\ + } elsif ($period eq "_Quarter") {\ + $value = ($QuarterPrevious ne "null") ? sprintf("%04d", ::ReadingsVal($QuarterBefore,$QuarterPrevious."_".$reading,0) ) : "";;\ + return $value;;\ + } elsif ($period eq "_Year") {\ + $value = sprintf("%05d",::ReadingsVal($device,$reading.$period,0)/1000);;\ + $value .= ($YearPrevious ne "null") ? sprintf(" / %05d", ::ReadingsVal($YearBefore,$reading.$period,0) ) : "";;\ + return $value;;\ + }\ + return " / null";;\ +}\ +\ +}\ +\ +\ +"Statistiken ".::POSIX::strftime("%Y-%m-%d",localtime(::time_str2num(::ReadingsTimestamp("WR_1_API", "auth_me_authenticated",0))))." in kWh"|\ +"aktuell"|\ +"heute".WR_ctl_Format("_Dx","WR_1_API","SW_Statistic_Yield").""|\ +|\ +"Monat".WR_ctl_Format("_Mx","WR_1_API","SW_Statistic_Yield").""|\ +"".WR_ctl_Format("_Qx","none","none").""|\ +"Jahr".WR_ctl_Format("_Yx","none","SW_Statistic_Yield").""\ +\ +"Erzeugung PV-Total"|\ +sprintf("%04d W",[WR_1:SW_Total_AC_Active_P])|\ +WR_ctl_Format("_Day","WR_1_API","SW_Statistic_Yield")|\ +|\ +WR_ctl_Format("_Month","WR_1_API","SW_Statistic_Yield")|\ +WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_Yield")|\ +WR_ctl_Format("_Year","WR_1_API","SW_Statistic_Yield")\ +\ +"Bezug von PV"|\ +sprintf("%04d W",[WR_1:SW_Home_own_consumption_from_Battery]+[WR_1:SW_Home_own_consumption_from_PV])|\ +WR_ctl_Format("_Day","WR_1_API","SW_Statistic_EnergyHomePv")|\ +|\ +WR_ctl_Format("_Month","WR_1_API","SW_Statistic_EnergyHomePv")|\ +WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_EnergyHomePv")|\ +WR_ctl_Format("_Year","WR_1_API","SW_Statistic_EnergyHomePv")\ +\ +"Bezug von Batterie"|\ +sprintf("%04d W",[WR_1:SW_Home_own_consumption_from_Battery])|\ +WR_ctl_Format("_Day","WR_1_API","Statistic_EnergyHomeBat")|\ +|\ +WR_ctl_Format("_Month","WR_1_API","Statistic_EnergyHomeBat")|\ +WR_ctl_Format("_Quarter","WR_1_API","Statistic_EnergyHomeBat")|\ +WR_ctl_Format("_Year","WR_1_API","Statistic_EnergyHomeBat")\ +\ +"Bezug vom Netz"|\ +sprintf("%04d W",([WR_1:Total_Active_P_EM] >= 0 ? ::round(::ReadingsVal("WR_1","Total_Active_P_EM",0),0) : 0) )|\ +WR_ctl_Format("_Day","WR_1_API","SW_Statistic_EnergyHomeGrid")|\ +|\ +WR_ctl_Format("_Month","WR_1_API","SW_Statistic_EnergyHomeGrid")|\ +WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_EnergyHomeGrid")|\ +WR_ctl_Format("_Year","WR_1_API","SW_Statistic_EnergyHomeGrid")\ +\ +"Bezug ins Haus (Energieverbrauch)"|\ +sprintf("%04d W",[WR_1:SW_Home_own_consumption_from_PV]+[WR_1:SW_Home_own_consumption_from_Battery]+[WR_1:SW_Home_own_consumption_from_grid])|\ +WR_ctl_Format("_Day","WR_1_API","SW_Statistic_TotalConsumption")|\ +|\ +WR_ctl_Format("_Month","WR_1_API","SW_Statistic_TotalConsumption")|\ +WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_TotalConsumption")|\ +WR_ctl_Format("_Year","WR_1_API","SW_Statistic_TotalConsumption")\ +\ +"Einspeisung ins Netz"|\ +sprintf("%04d W",([WR_1:Total_Active_P_EM] <= 0 ? abs(::round(::ReadingsVal("WR_1","Total_Active_P_EM",0),0)) : 0) )|\ +WR_ctl_Format("_Day","WR_1_API","SW_Statistic_EnergyHomeFeedInGrid")|\ +|\ +WR_ctl_Format("_Month","WR_1_API","SW_Statistic_EnergyHomeFeedInGrid")|\ +WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_EnergyHomeFeedInGrid")|\ +WR_ctl_Format("_Year","WR_1_API","SW_Statistic_EnergyHomeFeedInGrid")\ +\ +"Autarkiequote"|\ +WR_ctl_Format("actual","WR_1","Autarky")|\ +WR_ctl_Format("_Day","WR_1_API","SW_Statistic_Autarky")|\ +|\ +WR_ctl_Format("_Month","WR_1_API","SW_Statistic_Autarky")|\ +|\ +WR_ctl_Format("Autarky_Year","WR_1_API","SW_Statistic_Autarky")\ +\ +"Eigenverbrauchsquote"|\ +WR_ctl_Format("actual","WR_1","OwnConsumptionRate")|\ +WR_ctl_Format("_Day","WR_1_API","SW_Statistic_OwnConsumptionRate")|\ +|\ +WR_ctl_Format("_Month","WR_1_API","SW_Statistic_OwnConsumptionRate")|\ +|\ +WR_ctl_Format("OwnConsumptionRate_Year","WR_1_API","SW_Statistic_OwnConsumptionRate")\ +\ +"Berechnet um"|\ +|\ +WR_ctl_Format("time_Day","WR_1_API","SW_Statistic_Autarky")|\ +|\ +WR_ctl_Format("time_Month","WR_1_API","SW_Statistic_Autarky")|\ +WR_ctl_Format("time_Quarter","WR_1_API","")|\ +WR_ctl_Format("time_Year","WR_1_API","SW_Statistic_Autarky")\ + +attr WR_ctl userReadings Yield_fc0_current:Yield_fc0_18.* { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;; ::ReadingsVal("$NAME","Yield_fc0_".sprintf("%02d",$hour),0)/1000 },\ +Yield_fc1_current:Yield_fc1_18.* { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;; ::ReadingsVal("$NAME","Yield_fc1_".sprintf("%02d",$hour),0)/1000 } +attr WR_ctl verbose 3 + +setstate WR_ctl 2023-06-21 11:33:15 SpeicherMidday_Inverter_Max_Power 9000 +setstate WR_ctl 2024-01-24 16:03:00 ui_command_1 --- +setstate WR_ctl 2024-01-24 15:57:00 ui_command_2 --- diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wirlpool_Shelly_2.5/.gitkeep b/fhem/contrib/ch.eick/Photovoltaik/Wirlpool_Shelly_2.5/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/fhem/contrib/ch.eick/Photovoltaik/Wärmepumpe_Novelan_LAD9/.gitkeep b/fhem/contrib/ch.eick/Photovoltaik/Wärmepumpe_Novelan_LAD9/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_EVU_Tibber.txt b/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_EVU_Tibber.txt new file mode 100644 index 000000000..bf3134797 --- /dev/null +++ b/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_EVU_Tibber.txt @@ -0,0 +1,264 @@ +defmod EVU_Tibber DOIF ## Startup Befehle für den WebSocket vom EVU_Tibber_connect\ +init\ +{ \ + Log(0, "$SELF 0 init : ▶️ EVU_Tibber init");;\ + fhem("setreading EVU_Tibber_connect ws_cmd connect");; \ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 0 WebSocket : ▶️ EVU_Tibber_connect start Websocket";;\ + }\ + Log(0, "$SELF 0 init : 🏁 EVU_Tibber init done");;\ +}\ +\ +################################################################################################################\ +## EVU_Tibber_connect start/stop WebSocket\ +EVU_Tibber_connect_ws\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ +# or [$SELF:ui_command_2] ## Hier wird das uiTable select ausgewertet\ + and [$SELF:ui_command_2] ne "---"\ + ) {\ +\ + fhem("setreading EVU_Tibber_connect ws_cmd ".[?$SELF:ui_command_2]);; \ +\ + set_Reading("ui_command_2","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 1 Scheduling für das Abholen von Tibber Daten\ +1_EVU_Tibber_PriceInfo\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ( [:03] ## Kurz nach jeder vollen Stunde\ + )\ + or [$SELF:ui_command_1] eq "1_EVU_Tibber_PriceInfo" ## Hier wird das uiTable select ausgewertet\ + ) {\ +\ + ::CommandGet(undef, "EVU_Tibber_connect 01_priceInfo");; ## Preis für die aktuelle Stunde\ + ::CommandGet(undef, "EVU_Tibber_connect 03_consumption_hour");; ## Kosten der letzen drei Stunden\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 1 PriceInfo : Abfrage von Tibber";;\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 2 Scheduling für das Abholen der Tibber Preise\ +2_EVU_Tibber_PriceAll\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ([00:03] or [14:03] ## Ab 14:00 Uhr gibt es die Preise für den nächsten Tag\ + )\ + or [$SELF:ui_command_1] eq "2_EVU_Tibber_PriceAll" ## Hier wird das uiTable select ausgewertet\ + ) {\ +\ + ::CommandGet(undef, "EVU_Tibber_connect 02_priceAll");;\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 2 priceAll : Abfrage von Tibber für den nächsten Tag";;\ + }\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ +\ +################################################################################################################\ +## 2 Erstellen des Diagramms im uiTable\ +3_EVU_Tibber_Diagramm\ +{if( !([$SELF:state] eq "off") ## DOIF enabled\ + and\ + ( [00:05] or [14:05] ## Kurz nach Mitternacht\ + )\ + or [$SELF:ui_command_1] eq "3_EVU_Tibber_Diagramm" ## Hier wird das uiTable select ausgewertet\ + ) {\ +\ + my (@out) = ("") x 2;;\ + my $timestamp;;\ +\ + for (my $j=0;;$j<=1;;$j++){\ +\ + if (ReadingsVal("EVU_Tibber_connect",sprintf("fc%d_00_startsAt",$j),"null") eq "null") { ## Der nächste Tag ist noch nicht da\ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 3 Diagramm : Tibber Daten für fc".$j." sind noch nicht da";;\ + }\ +\ + $timestamp = POSIX::strftime("%Y-%m-%d",localtime(time+86400));; ## Setze das Datum auf morgen\ + for (my $k=0;;$k<=24;;$k++) {\ + $out[$j] .= sprintf("%s_%02d:00:00 0.0\n", $timestamp, $k);; ## Die Daten mit 0 ergänzen\ + }\ + $j = 2;; ## Aus der Schleife springen\ +\ + } else {\ +\ + for (my $i=0;;$i<=23;;$i++){\ + $timestamp = ReadingsVal("EVU_Tibber_connect",sprintf("fc%d_%02d_startsAt",$j,$i),"");;\ + $timestamp =~ s/ /_/g;;\ + $out[$j] .=$timestamp." ".::round(ReadingsVal("EVU_Tibber_connect",sprintf("fc%d_%02d_total",$j, $i),0)*100,1)."\n";;\ + } # End $i\ +\ + } # End if\ + } # End $j\ + \ + if (AttrVal("$SELF","verbose",0) >=3) {\ + Log 3, "$SELF 3 Diagramm : Werte für das Diagramm";;\ + print($out[0]);;\ + print($out[1]);;\ + }\ + ## Die readings current_price und current_level dienen hier nur als Trigger Events, und müssen für\ + ## jedes Diagramm unterschiedlich sein, die Daten werden über $out[] bereit gestellt !!\ + ::DOIF_modify_card_data("EVU_Tibber","EVU_Tibber_connect","current_price","bar1day",0,$out[0]);;\ + ::DOIF_modify_card_data("EVU_Tibber","EVU_Tibber_connect","current_level","bar1day",-86400,$out[1]);;\ + ## Mit der Abfrage 03_consumption_hour werden die Trigger erneut ausgelöst\ + ::CommandGet(undef, "EVU_Tibber_connect 01_priceInfo");; ## Kosten der letzen drei Stunden\ +## fhem("get EVU_Tibber_connect 01_priceInfo");; ## Kosten der letzen drei Stunden\ +\ + set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ + ## kann das Kommando nicht sofort wiederholt werden\ + }\ +}\ + +attr EVU_Tibber DbLogExclude .* +attr EVU_Tibber comment Version 2023.12.06 13:00 \ +Dieses Device benötigt EVU_Tibber_connect als Verbindung zu Tibber. +attr EVU_Tibber disable 0 +attr EVU_Tibber group PV Steuerung EVU +attr EVU_Tibber icon stromzaehler_icon +attr EVU_Tibber room Strom->Boerse +attr EVU_Tibber sortby 315 +attr EVU_Tibber uiState {\ +package ui_Table;;\ + $TABLE = "style='width:100%;;'";;\ +\ + $TD{0..6}{0} = "style='border-top-style:solid;;border-bottom-style:solid;;border-left-style:solid;;border-left-width:2px;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ + $TD{0..6}{1..4} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ + $TD{0..6}{5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ +\ +}\ +\ +"Kommando
Auswahl
" |widget([$SELF:ui_command_1],"uzsuDropDown,---,1_EVU_Tibber_PriceInfo,2_EVU_Tibber_PriceAll,3_EVU_Tibber_Diagramm") |"LiveMessurement
".widget([$SELF:ui_command_2],"uzsuDropDown,---,connect,disconnect")|""|[EVU_Tibber_connect:ws_cmd]\ +\ +"Strompreis
".card([EVU_Tibber_connect:current_price:bar1day],undef,undef,0,60,90,0,"fc0 ".::ReadingsVal(Device(),"current_currency",""),undef,"1","130,,,,,,220").card([EVU_Tibber_connect:current_level:bar1day],undef,undef,0,60,90,0,"fc1 ".::ReadingsVal(Device(),"current_currency",""),undef,"1","130,,,,,,220")|\ +"nächste 3h

".Price(1)."
".Price(2)."
".Price(3)|"Statistik fc0

".::ReadingsVal(Device(),"fc_min",0)." min
".::ReadingsVal(Device(),"fc_avg",0)." avg
".::ReadingsVal(Device(),"fc_med",0)." med
".::ReadingsVal(Device(),"fc_max",0)." max"|\ +"Trigger fc0
Basis ".widget([EVU_Tibber_connect:compensation_grid],"selectnumbers,0,0.1,12,1,lin")."
".Format("trigger_0")|\ +"Trigger fc1

".Format("trigger_1") +attr EVU_Tibber uiTable {\ +package ui_Table;;\ + $TABLE = "style='width:100%;;'";;\ +\ + $TD{0..18}{0} = "style='border-top-style:solid;;border-bottom-style:solid;;border-left-style:solid;;border-left-width:2px;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ + $TD{0..18}{1..5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ + $TD{0..18}{6} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ +\ +sub FUNC_Status {\ + my($value, $min, $colorMin, $statusMin, $colorMiddel, $statusMiddle, $max, $colorMax, $statusMax)=@_;;\ + my $ret = ($value < $min)? ''.$statusMin.'' : ($value > $max)? ''.$statusMax.'' : ''.$statusMiddle.'';;\ + return $ret;;\ + }\ +\ +sub Device {\ + return "$SELF"."_connect";;\ + }\ +\ +sub Cost {\ + my($i)=@_;;\ + my $currency = (::ReadingsVal(Device(),"current_currency","") eq "EUR")? " €" : "";;\ +\ + return ::ReadingsVal(Device(),"total_cost_".$i,0).$currency;;\ +}\ +\ +sub Price {\ + my($i)=@_;;\ + my $j;;\ + my $value;;\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;;\ +\ + if ($i == 0) {\ + $value = ::ReadingsVal(Device(),"current_price",0);;\ + $value = ( ::ReadingsVal(Device(),"fc0_trigger","off") eq "on" ) ?\ + "".$value."" :\ + "".$value."" ;;\ + $value .= " ct/kWh";;\ + } else {\ + $j = $i+$hour;;\ + if ($j < 24) {\ + $value = ::round(::ReadingsVal(Device(),"fc0_".sprintf("%02d",$j)."_total",0)*100,1);;\ + } else {\ + $j = $j - 24;;\ + $value = ::round(::ReadingsVal(Device(),"fc1_".sprintf("%02d",$j)."_total",0)*100,1);;\ + }\ + $value = ( ::ReadingsVal(Device(),"fc_trigger_price","0") > $value ) ?\ + "".$value."" :\ + "".$value."" ;;\ + $value = sprintf("%02d",$j)." : ".$value ;;\ + }\ + return $value;;\ + }\ +\ +sub Format {\ + my($i)=@_;;\ +\ + my $MonthBefore = "LogDBRep_Statistic_previous_Month";;\ + my $MonthPrevious = ::ReadingsTimestamp("$MonthBefore",Device()."_nodes_consumption_month","null");;\ + $MonthPrevious = ($MonthPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp("$MonthBefore",Device()."_nodes_consumption_month","null")))) : "null";;\ +\ + my $YearBefore = "LogDBRep_Statistic_previous_Year";;\ + my $YearPrevious = ::ReadingsTimestamp("$YearBefore",Device()."_nodes_consumption_year","null");;\ + $YearPrevious = ($YearPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp("$YearBefore",Device()."_nodes_consumption_year","null")))) : "null";;\ +\ + if ($i eq "day") {\ + return sprintf("%04d",::ReadingsVal(Device(),"nodes_consumption_day",0));;\ + } elsif ($i eq "month") {\ + my $evu_em = sprintf("%04d",::ReadingsVal(Device(),"nodes_consumption_month",0));;\ + $evu_em .= ($MonthPrevious ne "null") ? sprintf(" / %04d", ::ReadingsVal("$MonthBefore",Device()."_nodes_consumption_month",0) ) : "";;\ + return $evu_em;;\ + } elsif ($i eq "year") {\ + my $evu_ey = sprintf("%04d",::ReadingsVal(Device(),"nodes_consumption_year",0));;\ + $evu_ey .= ($YearPrevious ne "null") ? sprintf(" / %04d", ::ReadingsVal("$YearBefore",Device()."_nodes_consumption_month",0) ) : "";;\ + return $evu_ey;;\ + } elsif ($i eq "trigger_0") {\ + return ((::ReadingsVal(Device(),"fc0_trigger_start","") eq "null" ) ?\ + "Heute kein Trigger
mehr unter ".\ + ::ReadingsVal(Device(),"fc_trigger_price","null")." ct
" :\ + "Trigger von
".\ + ::ReadingsVal(Device(),"fc0_trigger_start","00:00")." bis ".::ReadingsVal(Device(),"fc0_trigger_stop","00:00")."
unter ".\ + ::ReadingsVal(Device(),"fc_trigger_price","null")." ct
" );;\ + } elsif ($i eq "trigger_1") {\ + if (::ReadingsVal(Device(),"fc1_00_startsAt","null") ne "null") {\ + return ((::ReadingsVal(Device(),"fc1_trigger_start","null") eq "null" ) ?\ + "Morgen kein Trigger
mehr unter ".\ + ::ReadingsVal(Device(),"fc_trigger_price","null")." ct
" :\ + "Morgen ein Trigger von
".\ + ::ReadingsVal(Device(),"fc1_trigger_start","00:00")." bis ".::ReadingsVal(Device(),"fc1_trigger_stop","00:00")."
unter ".\ + ::ReadingsVal(Device(),"fc_trigger_price","null")." ct
" );;\ + } else {\ + return "Morgen noch kein Trigger vorhanden";;\ + }\ + }\ + return "null";;\ +}\ +\ +}\ +\ +"Statistiken ".::ReadingsVal(Device(),"current_date",0)." in kWh"|"aktuell"|"heute"|"Monat"|"Jahr"\ +\ +"Strom
Preis / Kosten
"|Price(0)|Cost("day")|Cost("month")|Cost("year")\ +\ +## Wenn man das liveMessurment von Tibber verwendet\ +"Bezug vom Netz"|\ +sprintf("%04d W",([EVU_Tibber_connect:payload_data_liveMeasurement_power] >= 0 ? ::ReadingsVal("EVU_Tibber_connect","payload_data_liveMeasurement_power",0) : 0))|\ +Format("day")|Format("month")|Format("year")\ +\ +"Einspeisung ins Netz"|\ +sprintf("%04d W",([EVU_Tibber_connect:payload_data_liveMeasurement_powerProduction] >= 0 ? ::ReadingsVal("EVU_Tibber_connect","payload_data_liveMeasurement_powerProduction",0) : 0))|\ +""|""|""\ +\ +## Wenn man einen eigenes SmartMeter verwendet\ +## "Bezug vom Netz"|sprintf("%04d W",([WR_0_KSEM:M_AC_Power] >= 0 ? ::round(::ReadingsVal("WR_0_KSEM","M_AC_Power",0),0) : 0) )|Format("day")|Format("month")|Format("year")\ +## "Einspeisung ins Netz"|sprintf("%04d W",([WR_0_KSEM:M_AC_Power] <= 0 ? abs(::round(::ReadingsVal("WR_0_KSEM","M_AC_Power",0),0)) : 0) )|""|""|"" +attr EVU_Tibber verbose 3 + +setstate EVU_Tibber 2024-01-23 10:03:00 ui_command_1 --- +setstate EVU_Tibber 2024-01-20 17:40:53 ui_command_2 --- \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_EVU_Tibber_connect.txt b/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_EVU_Tibber_connect.txt new file mode 100644 index 000000000..51ba627c1 --- /dev/null +++ b/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_EVU_Tibber_connect.txt @@ -0,0 +1,1250 @@ +defmod EVU_Tibber_connect HTTPMOD https://api.tibber.com/v1-beta/gql 0 +attr EVU_Tibber_connect userattr ws_homeId ws_minInterval ws_myId ws_token ws_websocketURL +attr EVU_Tibber_connect DbLogExclude .* +attr EVU_Tibber_connect DbLogInclude total_cost_.*,fc0_trigger.* +attr EVU_Tibber_connect comment Version 2024.01.22 14:00 \ +https://developer.tibber.com/explorer\ +\ +In der FHEM Kommandozeile könnt Ihr das token und die homeID im KeyStore ablegen.\ +Bitte lest dazu das Thema KeyStore im Wiki und legt die Funktion in Eure 99_myUtils.\ +\ +{KeyValue("store","EVU_Tibber_connect_token","5K4MVS-OjfWhK_4yrjOlFe1F6kJXPVf7eQYggo8ebAE")}\ +{KeyValue("store","EVU_Tibber_connect_homeID","96a14971-525a-4420-aae9-e5aedaa129ff")}\ +\ +Hierduch kann man einen wirtschaftlicheren trigger_price berechnen lassen:\ +setreading EVU_Tibber compensation_grid \ +\ +# Berechnung eines Default Schwellwertes als täglicher Niedrigpreis\ + (fc_avg - fc_min) /2 + fc_min\ +\ +# Abschätzung von Wirtschaftlichkeit beim Speicher Laden, falls Tibber zu teuer wird\ +# compensation_grid kann auch auf einen für Euch passenden Wert gesetzt werden\ + (fc_avg - compensation_grid) *0.85 +attr EVU_Tibber_connect disable 0 +attr EVU_Tibber_connect enableControlSet 1 +attr EVU_Tibber_connect get01-1Name current_currency +attr EVU_Tibber_connect get01-2Name current_level +attr EVU_Tibber_connect get01-3Name current_date +attr EVU_Tibber_connect get01-3OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get01-4Name current_price +attr EVU_Tibber_connect get01-4OExpr $val *100 +attr EVU_Tibber_connect get01Data { "query": "{viewer {home(id:\"%%homeID%%\") {currentSubscription {priceInfo {current {total startsAt currency level}}}}}}" } +attr EVU_Tibber_connect get01Header01 Content-Type: application/json +attr EVU_Tibber_connect get01Header02 Authorization: Bearer %%token%% +attr EVU_Tibber_connect get01JSON data_viewer_home_currentSubscription_priceInfo_current +attr EVU_Tibber_connect get01Name 01_priceInfo +attr EVU_Tibber_connect get01URL https://api.tibber.com/v1-beta/gql +attr EVU_Tibber_connect get02-10Name fc0_03_total +attr EVU_Tibber_connect get02-11Name fc0_04_startsAt +attr EVU_Tibber_connect get02-11OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-12Name fc0_04_total +attr EVU_Tibber_connect get02-13Name fc0_05_startsAt +attr EVU_Tibber_connect get02-13OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-14Name fc0_05_total +attr EVU_Tibber_connect get02-15Name fc0_06_startsAt +attr EVU_Tibber_connect get02-15OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-16Name fc0_06_total +attr EVU_Tibber_connect get02-17Name fc0_07_startsAt +attr EVU_Tibber_connect get02-17OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-18Name fc0_07_total +attr EVU_Tibber_connect get02-19Name fc0_08_startsAt +attr EVU_Tibber_connect get02-19OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-1Name current_date +attr EVU_Tibber_connect get02-1OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-20Name fc0_08_total +attr EVU_Tibber_connect get02-21Name fc0_09_startsAt +attr EVU_Tibber_connect get02-21OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-22Name fc0_09_total +attr EVU_Tibber_connect get02-23Name fc0_10_startsAt +attr EVU_Tibber_connect get02-23OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-24Name fc0_10_total +attr EVU_Tibber_connect get02-25Name fc0_11_startsAt +attr EVU_Tibber_connect get02-25OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-26Name fc0_11_total +attr EVU_Tibber_connect get02-27Name fc0_12_startsAt +attr EVU_Tibber_connect get02-27OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-28Name fc0_12_total +attr EVU_Tibber_connect get02-29Name fc0_13_startsAt +attr EVU_Tibber_connect get02-29OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-2Name current_price +attr EVU_Tibber_connect get02-2OExpr $val *100 +attr EVU_Tibber_connect get02-30Name fc0_13_total +attr EVU_Tibber_connect get02-31Name fc0_14_startsAt +attr EVU_Tibber_connect get02-31OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-32Name fc0_14_total +attr EVU_Tibber_connect get02-33Name fc0_15_startsAt +attr EVU_Tibber_connect get02-33OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-34Name fc0_15_total +attr EVU_Tibber_connect get02-35Name fc0_16_startsAt +attr EVU_Tibber_connect get02-35OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-36Name fc0_16_total +attr EVU_Tibber_connect get02-37Name fc0_17_startsAt +attr EVU_Tibber_connect get02-37OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-38Name fc0_17_total +attr EVU_Tibber_connect get02-39Name fc0_18_startsAt +attr EVU_Tibber_connect get02-39OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-3Name fc0_00_startsAt +attr EVU_Tibber_connect get02-3OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-40Name fc0_18_total +attr EVU_Tibber_connect get02-41Name fc0_19_startsAt +attr EVU_Tibber_connect get02-41OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-42Name fc0_19_total +attr EVU_Tibber_connect get02-43Name fc0_20_startsAt +attr EVU_Tibber_connect get02-43OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-44Name fc0_20_total +attr EVU_Tibber_connect get02-45Name fc0_21_startsAt +attr EVU_Tibber_connect get02-45OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-46Name fc0_21_total +attr EVU_Tibber_connect get02-47Name fc0_22_startsAt +attr EVU_Tibber_connect get02-47OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-48Name fc0_22_total +attr EVU_Tibber_connect get02-49Name fc0_23_startsAt +attr EVU_Tibber_connect get02-49OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-4Name fc0_00_total +attr EVU_Tibber_connect get02-50Name fc0_23_total +attr EVU_Tibber_connect get02-51Name fc1_00_startsAt +attr EVU_Tibber_connect get02-51OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-52Name fc1_00_total +attr EVU_Tibber_connect get02-53Name fc1_01_startsAt +attr EVU_Tibber_connect get02-53OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-54Name fc1_01_total +attr EVU_Tibber_connect get02-55Name fc1_02_startsAt +attr EVU_Tibber_connect get02-55OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-56Name fc1_02_total +attr EVU_Tibber_connect get02-57Name fc1_03_startsAt +attr EVU_Tibber_connect get02-57OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-58Name fc1_03_total +attr EVU_Tibber_connect get02-59Name fc1_04_startsAt +attr EVU_Tibber_connect get02-59OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-5Name fc0_01_startsAt +attr EVU_Tibber_connect get02-5OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-60Name fc1_04_total +attr EVU_Tibber_connect get02-61Name fc1_05_startsAt +attr EVU_Tibber_connect get02-61OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-62Name fc1_05_total +attr EVU_Tibber_connect get02-63Name fc1_06_startsAt +attr EVU_Tibber_connect get02-63OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-64Name fc1_06_total +attr EVU_Tibber_connect get02-65Name fc1_07_startsAt +attr EVU_Tibber_connect get02-65OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-66Name fc1_07_total +attr EVU_Tibber_connect get02-67Name fc1_08_startsAt +attr EVU_Tibber_connect get02-67OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-68Name fc1_08_total +attr EVU_Tibber_connect get02-69Name fc1_09_startsAt +attr EVU_Tibber_connect get02-69OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-6Name fc0_01_total +attr EVU_Tibber_connect get02-70Name fc1_09_total +attr EVU_Tibber_connect get02-71Name fc1_10_startsAt +attr EVU_Tibber_connect get02-71OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-72Name fc1_10_total +attr EVU_Tibber_connect get02-73Name fc1_11_startsAt +attr EVU_Tibber_connect get02-73OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-74Name fc1_11_total +attr EVU_Tibber_connect get02-75Name fc1_12_startsAt +attr EVU_Tibber_connect get02-75OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-76Name fc1_12_total +attr EVU_Tibber_connect get02-77Name fc1_13_startsAt +attr EVU_Tibber_connect get02-77OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-78Name fc1_13_total +attr EVU_Tibber_connect get02-79Name fc1_14_startsAt +attr EVU_Tibber_connect get02-79OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-7Name fc0_02_startsAt +attr EVU_Tibber_connect get02-7OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-80Name fc1_14_total +attr EVU_Tibber_connect get02-81Name fc1_15_startsAt +attr EVU_Tibber_connect get02-81OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-82Name fc1_15_total +attr EVU_Tibber_connect get02-83Name fc1_16_startsAt +attr EVU_Tibber_connect get02-83OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-84Name fc1_16_total +attr EVU_Tibber_connect get02-85Name fc1_17_startsAt +attr EVU_Tibber_connect get02-85OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-86Name fc1_17_total +attr EVU_Tibber_connect get02-87Name fc1_18_startsAt +attr EVU_Tibber_connect get02-87OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-88Name fc1_18_total +attr EVU_Tibber_connect get02-89Name fc1_19_startsAt +attr EVU_Tibber_connect get02-89OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-8Name fc0_02_total +attr EVU_Tibber_connect get02-90Name fc1_19_total +attr EVU_Tibber_connect get02-91Name fc1_20_startsAt +attr EVU_Tibber_connect get02-91OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-92Name fc1_20_total +attr EVU_Tibber_connect get02-93Name fc1_21_startsAt +attr EVU_Tibber_connect get02-93OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-94Name fc1_21_total +attr EVU_Tibber_connect get02-95Name fc1_22_startsAt +attr EVU_Tibber_connect get02-95OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-96Name fc1_22_total +attr EVU_Tibber_connect get02-97Name fc1_23_startsAt +attr EVU_Tibber_connect get02-97OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02-98Name fc1_23_total +attr EVU_Tibber_connect get02-9Name fc0_03_startsAt +attr EVU_Tibber_connect get02-9OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get02Data { "query": "{viewer {home(id:\"%%homeID%%\") {currentSubscription {priceInfo {current {total startsAt} today {total startsAt} tomorrow {total startsAt}}}}}}" } +attr EVU_Tibber_connect get02Header01 Content-Type: application/json +attr EVU_Tibber_connect get02Header02 Authorization: Bearer %%token%% +attr EVU_Tibber_connect get02JSON data_viewer_home_currentSubscription_priceInfo +attr EVU_Tibber_connect get02Name 02_priceAll +attr EVU_Tibber_connect get02URL https://api.tibber.com/v1-beta/gql +attr EVU_Tibber_connect get03-1Name nodes_00_00_from +attr EVU_Tibber_connect get03-1OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get03-2Name nodes_00_00_cost +attr EVU_Tibber_connect get03-2OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get03-3Name nodes_00_00_consumption +attr EVU_Tibber_connect get03-4Name nodes_00_01_from +attr EVU_Tibber_connect get03-4OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get03-50Name nodes_00_01_cost +attr EVU_Tibber_connect get03-50OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get03-5Name nodes_00_01_cost +attr EVU_Tibber_connect get03-5OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get03-6Name nodes_00_01_consumption +attr EVU_Tibber_connect get03-7Name nodes_00_02_from +attr EVU_Tibber_connect get03-7OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get03-8Name nodes_00_02_cost +attr EVU_Tibber_connect get03-8OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get03-9Name nodes_00_02_consumption +attr EVU_Tibber_connect get03Data { "query": "{viewer {home(id:\"%%homeID%%\") {consumption(resolution: HOURLY, last: 3) {nodes {from cost consumption }}}}}"} +attr EVU_Tibber_connect get03Header01 Content-Type: application/json +attr EVU_Tibber_connect get03Header02 Authorization: Bearer %%token%% +attr EVU_Tibber_connect get03Name 03_consumption_hour +attr EVU_Tibber_connect get03RegOpt g +attr EVU_Tibber_connect get03Regex \{"from":"([\d+-]+T[\d+:]+\.000[+-][\d+:]+)","cost":(null|\d+\.\d+|0),"consumption":(null|\d+\.\d+|0)\} +attr EVU_Tibber_connect get03URL https://api.tibber.com/v1-beta/gql +attr EVU_Tibber_connect get04-10Name nodes_24_03_from +attr EVU_Tibber_connect get04-10OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-11Name nodes_24_03_cost +attr EVU_Tibber_connect get04-11OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-12Name nodes_24_03_consumption +attr EVU_Tibber_connect get04-13Name nodes_24_04_from +attr EVU_Tibber_connect get04-13OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-14Name nodes_24_04_cost +attr EVU_Tibber_connect get04-14OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-15Name nodes_24_04_consumption +attr EVU_Tibber_connect get04-16Name nodes_24_05_from +attr EVU_Tibber_connect get04-16OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-17Name nodes_24_05_cost +attr EVU_Tibber_connect get04-17OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-18Name nodes_24_05_consumption +attr EVU_Tibber_connect get04-19Name nodes_24_06_from +attr EVU_Tibber_connect get04-19OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-1Name nodes_24_00_from +attr EVU_Tibber_connect get04-1OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-20Name nodes_24_06_cost +attr EVU_Tibber_connect get04-20OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-21Name nodes_24_06_consumption +attr EVU_Tibber_connect get04-22Name nodes_24_07_from +attr EVU_Tibber_connect get04-22OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-23Name nodes_24_07_cost +attr EVU_Tibber_connect get04-23OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-24Name nodes_24_07_consumption +attr EVU_Tibber_connect get04-25Name nodes_24_08_from +attr EVU_Tibber_connect get04-25OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-26Name nodes_24_08_cost +attr EVU_Tibber_connect get04-26OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-27Name nodes_24_08_consumption +attr EVU_Tibber_connect get04-28Name nodes_24_09_from +attr EVU_Tibber_connect get04-28OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-29Name nodes_24_09_cost +attr EVU_Tibber_connect get04-29OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-2Name nodes_24_00_cost +attr EVU_Tibber_connect get04-2OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-30Name nodes_24_09_consumption +attr EVU_Tibber_connect get04-31Name nodes_24_10_from +attr EVU_Tibber_connect get04-31OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-32Name nodes_24_10_cost +attr EVU_Tibber_connect get04-32OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-33Name nodes_24_10_consumption +attr EVU_Tibber_connect get04-34Name nodes_24_11_from +attr EVU_Tibber_connect get04-34OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-35Name nodes_24_11_cost +attr EVU_Tibber_connect get04-35OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-36Name nodes_24_11_consumption +attr EVU_Tibber_connect get04-37Name nodes_24_12_from +attr EVU_Tibber_connect get04-37OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-38Name nodes_24_12_cost +attr EVU_Tibber_connect get04-38OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-39Name nodes_24_12_consumption +attr EVU_Tibber_connect get04-3Name nodes_24_00_consumption +attr EVU_Tibber_connect get04-40Name nodes_24_13_from +attr EVU_Tibber_connect get04-40OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-41Name nodes_24_13_cost +attr EVU_Tibber_connect get04-41OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-42Name nodes_24_13_consumption +attr EVU_Tibber_connect get04-43Name nodes_24_14_from +attr EVU_Tibber_connect get04-43OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-44Name nodes_24_14_cost +attr EVU_Tibber_connect get04-44OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-45Name nodes_24_14_consumption +attr EVU_Tibber_connect get04-46Name nodes_24_15_from +attr EVU_Tibber_connect get04-46OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-47Name nodes_24_15_cost +attr EVU_Tibber_connect get04-47OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-48Name nodes_24_15_consumption +attr EVU_Tibber_connect get04-49Name nodes_24_16_from +attr EVU_Tibber_connect get04-49OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-4Name nodes_24_01_from +attr EVU_Tibber_connect get04-4OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-50Name nodes_24_16_cost +attr EVU_Tibber_connect get04-50OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-51Name nodes_24_16_consumption +attr EVU_Tibber_connect get04-52Name nodes_24_17_from +attr EVU_Tibber_connect get04-52OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-53Name nodes_24_17_cost +attr EVU_Tibber_connect get04-53OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-54Name nodes_24_17_consumption +attr EVU_Tibber_connect get04-55Name nodes_24_18_from +attr EVU_Tibber_connect get04-55OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-56Name nodes_24_18_cost +attr EVU_Tibber_connect get04-56OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-57Name nodes_24_18_consumption +attr EVU_Tibber_connect get04-58Name nodes_24_19_from +attr EVU_Tibber_connect get04-58OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-59Name nodes_24_19_cost +attr EVU_Tibber_connect get04-59OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-5Name nodes_24_01_cost +attr EVU_Tibber_connect get04-5OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-60Name nodes_24_19_consumption +attr EVU_Tibber_connect get04-61Name nodes_24_20_from +attr EVU_Tibber_connect get04-61OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-62Name nodes_24_20_cost +attr EVU_Tibber_connect get04-62OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-63Name nodes_24_20_consumption +attr EVU_Tibber_connect get04-64Name nodes_24_21_from +attr EVU_Tibber_connect get04-64OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-65Name nodes_24_21_cost +attr EVU_Tibber_connect get04-65OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-66Name nodes_24_21_consumption +attr EVU_Tibber_connect get04-67Name nodes_24_22_from +attr EVU_Tibber_connect get04-67OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-68Name nodes_24_22_cost +attr EVU_Tibber_connect get04-68OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-69Name nodes_24_22_consumption +attr EVU_Tibber_connect get04-6Name nodes_24_01_consumption +attr EVU_Tibber_connect get04-70Name nodes_24_23_from +attr EVU_Tibber_connect get04-70OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-71Name nodes_24_23_cost +attr EVU_Tibber_connect get04-71OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-72Name nodes_24_23_consumption +attr EVU_Tibber_connect get04-7Name nodes_24_02_from +attr EVU_Tibber_connect get04-7OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get04-8Name nodes_24_02_cost +attr EVU_Tibber_connect get04-8OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get04-9Name nodes_24_02_consumption +attr EVU_Tibber_connect get04Data { "query": "{viewer {home(id:\"%%homeID%%\") {consumption(resolution: HOURLY, last: 24) {nodes {from cost consumption}}}}}"} +attr EVU_Tibber_connect get04Header01 Content-Type: application/json +attr EVU_Tibber_connect get04Header02 Authorization: Bearer %%token%% +attr EVU_Tibber_connect get04Name 04_consumption_hour_24 +attr EVU_Tibber_connect get04RegOpt g +attr EVU_Tibber_connect get04Regex \{"from":"([\d+-]+T[\d+:]+\.000[+-][\d+:]+)","cost":(null|\d+\.\d+|0),"consumption":(null|\d+\.\d+|0)\} +attr EVU_Tibber_connect get04URL https://api.tibber.com/v1-beta/gql +attr EVU_Tibber_connect get05AutoNumLen 4 +attr EVU_Tibber_connect get05Data { "query": "{viewer {home(id:\"%%homeID%%\") {consumption(resolution: HOURLY, last: 100) {nodes {from cost consumption}}}}}"} +attr EVU_Tibber_connect get05Header01 Content-Type: application/json +attr EVU_Tibber_connect get05Header02 Authorization: Bearer %%token%% +attr EVU_Tibber_connect get05JSON data_viewer_home +attr EVU_Tibber_connect get05Name 05_consumption_hourly_100 +attr EVU_Tibber_connect get05URL https://api.tibber.com/v1-beta/gql +attr EVU_Tibber_connect get06-10Name Adresse_07_Telefon +attr EVU_Tibber_connect get06-11Name Adresse_01_Vorname +attr EVU_Tibber_connect get06-12Name Adresse_02_Nachname +attr EVU_Tibber_connect get06-1Name Adresse_03_Strasse +attr EVU_Tibber_connect get06-2Name Adresse_05_Ort +attr EVU_Tibber_connect get06-3Name Adresse_06_Land +attr EVU_Tibber_connect get06-4Name Adresse_05_Ort +attr EVU_Tibber_connect get06-5Name Adresse_06_Land +attr EVU_Tibber_connect get06-6Name Adresse_09_latitude +attr EVU_Tibber_connect get06-7Name Adresse_10_longitude +attr EVU_Tibber_connect get06-8Name Adresse_04_Plz +attr EVU_Tibber_connect get06-9Name Adresse_08_eMail +attr EVU_Tibber_connect get06Data { "query": "{viewer {home(id:\"%%homeID%%\") {address {address1 address2 address3 postalCode city country latitude longitude} owner {firstName lastName contactInfo {email mobile}}}}}" } +attr EVU_Tibber_connect get06Header01 Content-Type: application/json +attr EVU_Tibber_connect get06Header02 Authorization: Bearer %%token%% +attr EVU_Tibber_connect get06JSON data_viewer_home +attr EVU_Tibber_connect get06Name 06_address +attr EVU_Tibber_connect get06URL https://api.tibber.com/v1-beta/gql +attr EVU_Tibber_connect get07-10Name nodes_24_03_from +attr EVU_Tibber_connect get07-10OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-11Name nodes_24_03_cost +attr EVU_Tibber_connect get07-11OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-12Name nodes_24_03_consumption +attr EVU_Tibber_connect get07-13Name nodes_24_04_from +attr EVU_Tibber_connect get07-13OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-14Name nodes_24_04_cost +attr EVU_Tibber_connect get07-14OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-15Name nodes_24_04_consumption +attr EVU_Tibber_connect get07-16Name nodes_24_05_from +attr EVU_Tibber_connect get07-16OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-17Name nodes_24_05_cost +attr EVU_Tibber_connect get07-17OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-18Name nodes_24_05_consumption +attr EVU_Tibber_connect get07-19Name nodes_24_06_from +attr EVU_Tibber_connect get07-19OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-1Name features_realTimeConsumptionEnabled +attr EVU_Tibber_connect get07-1OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-20Name nodes_24_06_cost +attr EVU_Tibber_connect get07-20OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-21Name nodes_24_06_consumption +attr EVU_Tibber_connect get07-22Name nodes_24_07_from +attr EVU_Tibber_connect get07-22OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-23Name nodes_24_07_cost +attr EVU_Tibber_connect get07-23OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-24Name nodes_24_07_consumption +attr EVU_Tibber_connect get07-25Name nodes_24_08_from +attr EVU_Tibber_connect get07-25OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-26Name nodes_24_08_cost +attr EVU_Tibber_connect get07-26OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-27Name nodes_24_08_consumption +attr EVU_Tibber_connect get07-28Name nodes_24_09_from +attr EVU_Tibber_connect get07-28OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-29Name nodes_24_09_cost +attr EVU_Tibber_connect get07-29OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-2Name features_id +attr EVU_Tibber_connect get07-2OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-30Name nodes_24_09_consumption +attr EVU_Tibber_connect get07-31Name nodes_24_10_from +attr EVU_Tibber_connect get07-31OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-32Name nodes_24_10_cost +attr EVU_Tibber_connect get07-32OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-33Name nodes_24_10_consumption +attr EVU_Tibber_connect get07-34Name nodes_24_11_from +attr EVU_Tibber_connect get07-34OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-35Name nodes_24_11_cost +attr EVU_Tibber_connect get07-35OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-36Name nodes_24_11_consumption +attr EVU_Tibber_connect get07-37Name nodes_24_12_from +attr EVU_Tibber_connect get07-37OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-38Name nodes_24_12_cost +attr EVU_Tibber_connect get07-38OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-39Name nodes_24_12_consumption +attr EVU_Tibber_connect get07-3Name nodes_24_00_consumption +attr EVU_Tibber_connect get07-40Name nodes_24_13_from +attr EVU_Tibber_connect get07-40OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-41Name nodes_24_13_cost +attr EVU_Tibber_connect get07-41OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-42Name nodes_24_13_consumption +attr EVU_Tibber_connect get07-43Name nodes_24_14_from +attr EVU_Tibber_connect get07-43OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-44Name nodes_24_14_cost +attr EVU_Tibber_connect get07-44OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-45Name nodes_24_14_consumption +attr EVU_Tibber_connect get07-46Name nodes_24_15_from +attr EVU_Tibber_connect get07-46OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-47Name nodes_24_15_cost +attr EVU_Tibber_connect get07-47OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-48Name nodes_24_15_consumption +attr EVU_Tibber_connect get07-49Name nodes_24_16_from +attr EVU_Tibber_connect get07-49OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-4Name nodes_24_01_from +attr EVU_Tibber_connect get07-4OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-50Name nodes_24_16_cost +attr EVU_Tibber_connect get07-50OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-51Name nodes_24_16_consumption +attr EVU_Tibber_connect get07-52Name nodes_24_17_from +attr EVU_Tibber_connect get07-52OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-53Name nodes_24_17_cost +attr EVU_Tibber_connect get07-53OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-54Name nodes_24_17_consumption +attr EVU_Tibber_connect get07-55Name nodes_24_18_from +attr EVU_Tibber_connect get07-55OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-56Name nodes_24_18_cost +attr EVU_Tibber_connect get07-56OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-57Name nodes_24_18_consumption +attr EVU_Tibber_connect get07-58Name nodes_24_19_from +attr EVU_Tibber_connect get07-58OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-59Name nodes_24_19_cost +attr EVU_Tibber_connect get07-59OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-5Name nodes_24_01_cost +attr EVU_Tibber_connect get07-5OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-60Name nodes_24_19_consumption +attr EVU_Tibber_connect get07-61Name nodes_24_20_from +attr EVU_Tibber_connect get07-61OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-62Name nodes_24_20_cost +attr EVU_Tibber_connect get07-62OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-63Name nodes_24_20_consumption +attr EVU_Tibber_connect get07-64Name nodes_24_21_from +attr EVU_Tibber_connect get07-64OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-65Name nodes_24_21_cost +attr EVU_Tibber_connect get07-65OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-66Name nodes_24_21_consumption +attr EVU_Tibber_connect get07-67Name nodes_24_22_from +attr EVU_Tibber_connect get07-67OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-68Name nodes_24_22_cost +attr EVU_Tibber_connect get07-68OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-69Name nodes_24_22_consumption +attr EVU_Tibber_connect get07-6Name nodes_24_01_consumption +attr EVU_Tibber_connect get07-70Name nodes_24_23_from +attr EVU_Tibber_connect get07-70OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-71Name nodes_24_23_cost +attr EVU_Tibber_connect get07-71OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-72Name nodes_24_23_consumption +attr EVU_Tibber_connect get07-7Name nodes_24_02_from +attr EVU_Tibber_connect get07-7OExpr $val =~ s/T/ /g ;; substr($val,0,19) +attr EVU_Tibber_connect get07-8Name nodes_24_02_cost +attr EVU_Tibber_connect get07-8OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val +attr EVU_Tibber_connect get07-9Name nodes_24_02_consumption +attr EVU_Tibber_connect get07Data { "query": "{viewer {home(id:\"%%homeID%%\") {id features{realTimeConsumptionEnabled} } } }" } +attr EVU_Tibber_connect get07Header01 Content-Type: application/json +attr EVU_Tibber_connect get07Header02 Authorization: Bearer %%token%% +attr EVU_Tibber_connect get07JSON data_viewer_home +attr EVU_Tibber_connect get07Name 07_realTimeConsumptionEnabled +attr EVU_Tibber_connect get07RegOpt g +attr EVU_Tibber_connect get07Regex \{"from":"([\d+-]+T[\d+:]+\.000[+-][\d+:]+)","cost":(null|\d+\.\d+|0),"consumption":(null|\d+\.\d+|0)\} +attr EVU_Tibber_connect get07URL https://api.tibber.com/v1-beta/gql +attr EVU_Tibber_connect group PV Steuerung EVU +attr EVU_Tibber_connect icon stromzaehler_icon +attr EVU_Tibber_connect replacement01Mode expression +attr EVU_Tibber_connect replacement01Regex %%token%% +attr EVU_Tibber_connect replacement01Value {KeyValue("read","EVU_Tibber_connect_token")} +attr EVU_Tibber_connect replacement02Mode expression +attr EVU_Tibber_connect replacement02Regex %%homeID%% +attr EVU_Tibber_connect replacement02Value {KeyValue("read","EVU_Tibber_connect_homeID")} +attr EVU_Tibber_connect requestData { "query": "{viewer {home(id:\"%%homeID%%\") {currentSubscription {priceInfo {current {total energy tax startsAt }}}}}}" } +attr EVU_Tibber_connect requestHeader1 Content-Type: application/json +attr EVU_Tibber_connect requestHeader2 Authorization: Bearer %%token%% +attr EVU_Tibber_connect room Strom->Boerse +attr EVU_Tibber_connect showBody 1 +attr EVU_Tibber_connect showError 1 +attr EVU_Tibber_connect sortby 313 +attr EVU_Tibber_connect timeout 30 +attr EVU_Tibber_connect userReadings ws_connect:ws_cmd:.connect {\ + my $hash = $defs{$name};;\ + my $devState = DevIo_IsOpen($hash);;\ + return "Device already open" if (defined($devState));;\ + \ + # establish connection to websocket\ + # format must also include portnumber if a path is to be specified\ + $hash->{DeviceName} = AttrVal($name, "ws_websocketURL", "wss:echo.websocket.org:443");;\ + \ + # special headers needed for Tibber, see also Developer Tools in Browser\ + $hash->{header}{'Sec-WebSocket-Protocol'} = 'graphql-transport-ws';;\ + $hash->{header}{'Host'} = 'websocket-api.tibber.com';;\ + $hash->{header}{'Origin'} = 'https://developer.tibber.com';;\ + \ + # callback function when "select()" signals data for us\ + # websocket Ping/Pongs are treated in DevIo but still call this function\ + $hash->{directReadFn} = sub () {\ + my $hash = $defs{$name};;\ + \ + # we can read without closing the DevIo, because select() signalled data\ + my $buf = DevIo_SimpleRead($hash);;\ + \ + # if read fails, close device\ + if(!defined($buf)) {\ + DevIo_CloseDev($hash);;\ + $buf = "not_connected";;\ + }\ + \ + #Log(3, "$name:$reading: websocket data: >>>$buf<<<");;\ + \ + # only update our reading if buffer is not empty and if last update is older than minInterval\ + if ($buf ne "") {\ + my $websocketDataAge = ReadingsAge($name, "ws_websocketData", 3600);;\ + my $minInterval = AttrVal($name, "ws_minInterval", 0);;\ + my $isNext = ($buf =~ /.*id.*type.*next.*payload.*data.*liveMeasurement.*/s);;\ + \ + readingsBeginUpdate($hash);;\ + readingsBulkUpdate($hash, "ws_websocketData", "$buf") if ($isNext && $websocketDataAge > $minInterval);;\ + readingsBulkUpdate($hash, "ws_websocketData", "$buf") if (!$isNext);;\ + readingsEndUpdate($hash, 1);;\ + #Log(3, "$name:$reading: websocket data written to reading");;\ + }\ + };;\ + \ + # open DevIo websocket\ + DevIo_OpenDev($hash, 0, undef, sub(){\ + my ($hash, $error) = @_;;\ + return "$error" if ($error);;\ + \ + my $token = AttrVal($name, "ws_token", "???");;\ + $token = KeyValue("read","EVU_Tibber_connect_token") if ($token eq "???");;\ +\ + DevIo_SimpleWrite($hash, '{"type":"connection_init","payload":{"token":"'.$token.'"}}', 2);;\ + });;\ + readingsBulkUpdate($hash, "ws_websocketData", "");;\ + #Log(3, "$name:$reading: websocket data cleared in reading");;\ + \ + return POSIX::strftime("%H:%M:%S",localtime(time()));;\ +},\ +\ +ws_disconnect:ws_cmd:.disconnect {\ + Log(3, "$name: disconnect");;\ + my $hash = $defs{$name};;\ + RemoveInternalTimer($hash);;\ + DevIo_SimpleRead($hash);;\ + DevIo_CloseDev($hash);;\ +\ + return POSIX::strftime("%H:%M:%S",localtime(time()));;\ +},\ +\ +ws_onDisconnect {\ + my $myState = ReadingsVal($name, "state", "???");;\ + my $myData = ReadingsVal($name, "ws_websocketData", "???");;\ + return if ($myState ne "disconnected" and $myData ne "not_connected");;\ + \ + ## timer callback function, called after a few seconds to initiate a reconnect\ + my $timerFunction = sub() {\ + my ($arg) = @_;;\ + my $hash = $defs{$name};;\ + my $devState = DevIo_IsOpen($hash);;\ + \ + # only re-connect if device is not connected\ + readingsSingleUpdate($hash, "ws_cmd", "connect", 1) if (!defined($devState));;\ + };;\ + RemoveInternalTimer($name.$reading.'Timer');;\ + \ + # wait a random time before reconnect (exponential backoff TBD):\ + my $rwait = int(rand(200)) + 30;;\ + InternalTimer(gettimeofday() + $rwait, $timerFunction, $name.$reading.'Timer');;\ + \ + #set cmd to a new value, informs user and allows to retrigger when timer expires\ + my $hash = $defs{$name};;\ + readingsBulkUpdate($hash, "ws_cmd", "reconnect attempt in $rwait seconds");;\ + \ + return POSIX::strftime("%H:%M:%S",localtime(time()));;\ +},\ +\ +ws_onTimeout:ws_websocketData:.* {\ + #re-establish websocket connection if no data received in the past ten minutes\ + #but only if our reading "ws_cmd" was not set to the value "disconnect"\ +\ + #Log(3, "$name:$reading: websocket data triggert ws_onTimeout");;\ +\ + #timeout in seconds when the connection is considered dead\ + my $timeoutTime = 600;;\ + \ + # function to execute when timeout expired\ + # defining the function here in the userReading, allows us to insert variables directly\ + my $timerFunction = sub() {\ + my ($arg) = @_;;\ + my $hash = $defs{$name};;\ + my $rCmd = ReadingsVal($name, "ws_cmd", "???");;\ + my $age = ReadingsAge($name, "ws_websocketData", 0);;\ + \ + Log(3, "$name: onTimeoutTimer triggered >>$arg<<");;\ + \ + #do not do anything further if disconnect is on purpose\ + if ( $rCmd eq "disconnect" ) {\ + Log(3, "$name: ws_cmd was set to disconnect");;\ + return;;\ + }\ + \ + # for whatever reason, we triggered to soon (80%)\ + if ( $age < $timeoutTime*0.8 ) {\ + Log(3, "$name: ws_websocketData is not outdated");;\ + return;;\ + }\ + \ + DevIo_CloseDev($hash);;\ + Log(3, "$name: onTimeoutTimer closed DevIo...");;\ + \ + readingsSingleUpdate($hash, "ws_cmd", "connect", 1);;\ + Log(3, "$name: onTimeoutTimer set ws_cmd to value 'connect'");;\ + };;\ +\ + #Log(3, "$name:$reading: onTimeout function defined");;\ +\ + #remove/cancel previous timers, because we got fresh data and countdown starts again\ + RemoveInternalTimer($name.$reading.'Timer');;\ + \ + #set timer to expire and execute function defined above, give special arg as identifier\ + InternalTimer(gettimeofday() + $timeoutTime, $timerFunction, $name.$reading.'Timer');;\ + \ + return POSIX::strftime("%H:%M:%S",localtime(time()));;\ +},\ +\ +ws_onConnectionAck:ws_websocketData:.*connection_ack.* {\ + #ws_websocketData contains the string "connection_ack"\ + Log(3, "$name:$reading: got connection ack");;\ + \ + # do not proceed if connection is lost\ + my $hash = $defs{$name};;\ + my $devState = DevIo_IsOpen($hash);;\ + return "Device not open" if (!defined($devState));;\ +\ + readingsBulkUpdate($hash, "ws_cmd", "got connection ack");;\ + \ + my $homeId = AttrVal($name, "ws_homeId", "???");;\ + $homeId = KeyValue("read","EVU_Tibber_connect_homeID") if ($homeId eq "???");;\ +\ + my $myId = AttrVal($name, "ws_myId", "???");;\ + $myId = KeyValue("read","EVU_Tibber_connect_homeID") if ($myId eq "???");;\ + \ + # build the query, do it in pieces, the comma at the end caused perl errors\ + # so we put it together in this not very elegant way\ + my $json = '{ "id":"'. $myId .'", "type":"subscribe"'.", ";;\ + $json .= '"payload":{';;\ + $json .= '"variables":{}'.", ";;\ + $json .= '"extensions":{}'.", ";;\ + $json .= '"query":"subscription { liveMeasurement( homeId: \"'.$homeId.'\" ) ';;\ + #$json .= '{ timestamp power accumulatedConsumption accumulatedCost currency minPower averagePower maxPower signalStrength }}"';;\ + $json .= '{ timestamp power lastMeterConsumption accumulatedConsumption accumulatedProduction ';;\ + $json .= 'accumulatedProductionLastHour accumulatedCost accumulatedReward currency minPower averagePower maxPower ';;\ + $json .= 'powerProduction powerReactive powerProductionReactive minPowerProduction maxPowerProduction lastMeterProduction ';;\ + $json .= 'powerFactor voltagePhase1 voltagePhase2 voltagePhase3 signalStrength }}"';;\ + $json .= '}}';;\ + \ + #send the string via websocket as ASCII\ + Log(3, "$name:$reading: sending JSON: >>>$json<<<");;\ + DevIo_SimpleWrite($hash, $json, 2);;\ + \ + return POSIX::strftime("%H:%M:%S",localtime(time()));;\ +},\ +\ +ws_onNextLiveMeasurement:ws_websocketData:.*next.*payload.*data.*liveMeasurement.* {\ + #websocketData contains next-live-measurement-data\ + my $val = ReadingsVal($name, "ws_websocketData", "{}");;\ + my %res = %{json2nameValue($val, undef, undef, "payload_data_liveMeasurement.*")};;\ + \ + my $ret = "got values for:\n";;\ + foreach my $k (sort keys %res) {\ + $ret .= "$k\n";;\ + readingsBulkUpdate($hash, makeReadingName($k), $res{$k});;\ + }\ + return $ret;;\ +},\ +\ +nodes_TIMESTAMP:nodes_00_00_cost.* {\ +my ($timestamp,$value) = 2x0;;\ +my $tmp = 0;;\ +\ +for (my $loop_last = 0;; $loop_last <= 2;; $loop_last++) {\ + $timestamp = ReadingsVal("$NAME","nodes_00_".sprintf("%02d",$loop_last)."_from","null");;\ + $value = ReadingsVal("$NAME","nodes_00_".sprintf("%02d",$loop_last)."_cost","null");;\ +\ + if ( $value ne "null" ) {\ + # Eintragen der Kosten für die Stunde\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$timestamp."','$NAME','Tibber','nodes_cost','".$value."')\ + ON DUPLICATE KEY UPDATE\ + VALUE='".$value."';;") ;;\ + # Eintragen des Verbrauchs für die Stunde\ + $value = ReadingsVal("$NAME","nodes_00_".sprintf("%02d",$loop_last)."_consumption","null");;\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$timestamp."','$NAME','Tibber','nodes_consumption','".$value."')\ + ON DUPLICATE KEY UPDATE\ + VALUE='".$value."';;") ;;\ + } else {\ + $tmp = "null";;\ + }\ +} # end for\ +if ($tmp eq "null") {\ + $timestamp = $tmp\ +}\ +$timestamp;;\ +},\ +\ +nodes_TIMESTAMP:nodes_24_00_cost.* {\ +my ($timestamp,$value) = 2x0;;\ +my $tmp = 0;;\ +\ +for (my $loop_last = 0;; $loop_last <= 23;; $loop_last++) {\ + $timestamp = ReadingsVal("$NAME","nodes_24_".sprintf("%02d",$loop_last)."_from","null");;\ + $value = ReadingsVal("$NAME","nodes_24_".sprintf("%02d",$loop_last)."_cost","null");;\ +\ + if ( $value ne "null" ) {\ + # Eintragen der Kosten für die Stunde\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$timestamp."','$NAME','Tibber','nodes_cost','".$value."')\ + ON DUPLICATE KEY UPDATE\ + VALUE='".$value."';;") ;;\ + # Eintragen des Verbrauchs für die Stunde\ + $value = ReadingsVal("$NAME","nodes_24_".sprintf("%02d",$loop_last)."_consumption","null");;\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$timestamp."','$NAME','Tibber','nodes_consumption','".$value."')\ + ON DUPLICATE KEY UPDATE\ + VALUE='".$value."';;") ;;\ + } else {\ + $tmp = "null";;\ + }\ +} # end for\ +if ($tmp eq "null") {\ + $timestamp = $tmp\ +}\ +$timestamp;;\ +},\ +\ +nodes_TIMESTAMP:05_consumption_hourly_100-0001.* {\ +my ($timestamp,$value) = 2x0;;\ +\ +for (my $loop_last = 1;; $loop_last <= 300;; $loop_last += 3) {\ +\ + $timestamp = ReadingsVal("$NAME","05_consumption_hourly_100-".sprintf("%04d",$loop_last+2),"null");; # timestamp\ + $timestamp =~ s/T/ /g ;;\ + $timestamp = substr($timestamp,0,19);;\ + $value = ReadingsVal("$NAME","05_consumption_hourly_100-".sprintf("%04d",$loop_last+1),"null");; # cost\ +\ + if ( $value ne "" ) {\ + $value = round($value,4);;\ +# print $timestamp." ".$value."\n";;\ +\ + # Eintragen der Kosten für die Stunde\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$timestamp."','$NAME','Tibber','nodes_cost','".$value."')\ + ON DUPLICATE KEY UPDATE\ + VALUE='".$value."';;") ;;\ + # Eintragen des Verbrauchs für die Stunde\ + $value = ReadingsVal("$NAME","05_consumption_hourly_100-".sprintf("%04d",$loop_last),"null");; # consumption\ + $value = round($value,4);;\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$timestamp."','$NAME','Tibber','nodes_consumption','".$value."')\ + ON DUPLICATE KEY UPDATE\ + VALUE='".$value."';;") ;;\ + }\ +} # end for\ +\ +$timestamp;;\ +},\ +\ +nodes_cost_avg:nodes_TIMESTAMP.* {\ +## Berechnung des Tages Wertes\ + if ( ReadingsVal("$NAME","nodes_TIMESTAMP","null") ne "null" ) {\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT cast(avg(VALUE)*100 AS DECIMAL(4,2)) FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_cost'\ + AND TIMESTAMP >= curdate() ;;") ;;\ + } else {\ + ReadingsVal("$NAME","nodes_cost_avg","null")\ + }\ +},\ +\ +nodes_cost_min:nodes_TIMESTAMP.* {\ +## Ermittlung des minimal Wertes\ +if ( ReadingsVal("$NAME","nodes_TIMESTAMP","null") ne "null" ) {\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT cast(min(VALUE)*100 AS DECIMAL(4,2)) FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_cost'\ + AND TIMESTAMP >= curdate() ;;") ;;\ +} else {\ + ReadingsVal("$NAME","nodes_cost_min","null")\ +}\ +},\ +\ +nodes_cost_max:nodes_TIMESTAMP.* {\ +## Ermittlung des maximal Wertes\ + if ( ReadingsVal("$NAME","nodes_TIMESTAMP","null") ne "null" ) {\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT cast(max(VALUE)*100 AS DECIMAL(4,2)) FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_cost'\ + AND TIMESTAMP >= curdate() ;;") ;;\ + } else {\ + ReadingsVal("$NAME","nodes_cost_max","null")\ + }\ +},\ +\ +nodes_consumption_day:nodes_TIMESTAMP.* {\ +## Berechnung des Tages Verbrauches\ +::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT cast(sum(VALUE) AS DECIMAL(10,4)) FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_consumption'\ + AND date(TIMESTAMP) = curdate() ;;") ;;\ +},\ +\ +nodes_consumption_month:nodes_TIMESTAMP.* {\ +## Berechnung des Monats Verbrauches\ +::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT cast(sum(VALUE) AS DECIMAL(10,4)) FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_consumption'\ + AND YEAR(TIMESTAMP) = YEAR(curdate())\ + AND MONTH(TIMESTAMP) = MONTH(curdate()) ;;") ;;\ +},\ +\ +nodes_consumption_year:nodes_TIMESTAMP.* {\ +## Berechnung des Jahres Verbrauches\ +::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT cast(sum(VALUE) AS DECIMAL(10,4)) FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_consumption'\ + AND YEAR(TIMESTAMP) = YEAR(curdate()) ;;") ;;\ +},\ +\ +fc_avg:current_price.* {\ +## Berechnung des durchschnitt Wertes\ + my $fc_avg = 0;;\ + my $fc = 0;;\ +\ + if (ReadingsVal("$NAME","fc1_00_startsAt","null") ne "null") { ## Der nächste Tag ist bereits da\ + if (AttrVal("$NAME","verbose",0) >=3) {\ + Log 3, "$NAME cmd_1 : Tibber Daten für fc1 sind bereits da";;\ + }\ + $fc = 1;;\ + } # end if\ +\ + for (my $j=0;;$j<=$fc;;$j++){\ + for (my $k=0;;$k<=23;;$k++) { ## Summe berechnen\ + $fc_avg += ReadingsVal("$NAME",sprintf("fc%d_%02d_total",$j,$k),0);;\ + } # end $k\ + } # end $j\ +\ + return round($fc_avg / (24 *(1+$fc)) *100 ,2);; ## Durchschnitt berechnen\ +},\ +\ +fc_med:current_price.* {\ +## Berechnung des median Wertes\ +::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT\ + cast( ( (SUBSTRING_INDEX(SUBSTRING_INDEX(group_concat(VALUE order by VALUE), ',', floor(1+((count(VALUE)-1) / 2))) , ',', -1))\ + + (SUBSTRING_INDEX(SUBSTRING_INDEX(group_concat(VALUE order by VALUE), ',', ceiling(1+((count(VALUE)-1) / 2))), ',', -1))\ + )/2 *100\ + AS DECIMAL(4,2))\ + FROM history\ + WHERE DEVICE='".$NAME."'\ + AND ( READING='fc0_total' AND TIMESTAMP >= DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00')\ + OR READING='fc1_total' AND TIMESTAMP >= DATE_FORMAT(NOW() + INTERVAL 1 DAY, '%Y-%m-%d 00:00:00') ) ;;") ;;\ +},\ +\ +fc_min:current_price.* {\ +## Ermittlung des minimal Wertes\ + my $fc_min = 0;;\ + my $fc_tmp = 0;;\ + my $fc = 0;;\ +\ + if (ReadingsVal("$NAME","fc1_00_startsAt","null") ne "null") { ## Der nächste Tag ist bereits da\ + $fc = 1;;\ + } # end if\ +\ + for (my $j=0;;$j<=$fc;;$j++){\ + for (my $k=0;;$k<=23;;$k++) {\ + $fc_tmp = ReadingsVal("$NAME",sprintf("fc%d_%02d_total",$j,$k),0);;\ + \ + if (($fc_tmp < $fc_min) or ($j == 0 and $k == 0)) {\ + $fc_min = $fc_tmp;;\ + }\ + } # end $k\ + } # end $j\ +\ + return round($fc_min *100 ,2);; ## Von Euro auf Cent umrechnen\ +},\ +\ +fc_max:current_price.* {\ +## Ermittlung des minimal Wertes\ + my $fc_max = 0;;\ + my $fc_tmp = 0;;\ + my $fc = 0;;\ +\ + if (ReadingsVal("$NAME","fc1_00_startsAt","null") ne "null") { ## Der nächste Tag ist bereits da\ + $fc = 1;;\ + } # end if\ +\ + for (my $j=0;;$j<=$fc;;$j++){\ + for (my $k=0;;$k<=23;;$k++) {\ + $fc_tmp = ReadingsVal("$NAME",sprintf("fc%d_%02d_total",$j,$k),0);;\ + \ + if (($fc_tmp > $fc_max) or ($j == 0 and $k == 0)) {\ + $fc_max = $fc_tmp;;\ + }\ + } # end $k\ + } # end $j\ +\ + return round($fc_max *100 ,2);; ## Von Euro auf Cent umrechnen\ +},\ +\ +fc_trigger_price:fc_avg.* {\ +## fc_trigger_price:[fc_avg|compensation_grid].* {\ + my $fc_avg = ReadingsVal("$NAME","fc_avg",0);;\ + my $fc_min = ReadingsVal("$NAME","fc_min",0);;\ +\ + # Berechnung eines Default Schwellwertes als täglicher Niedrigpreis\ + my $price_level = round( ($fc_avg - $fc_min)/2 + $fc_min , 1);;\ + \ + # Abschätzung von Wirtschaftlichkeit beim Speicher Laden, falls Tibber zu teuer wird\ + if ( ReadingsVal("$NAME","compensation_grid",0) != 0 ) {\ + my $price_level_battery = round( ($fc_avg - ReadingsVal("$NAME","compensation_grid",0)) *0.85 , 1) ;;\ + if ( $price_level > $price_level_battery ) {\ + $price_level = $price_level_battery;;\ + }\ + }\ +$price_level;;\ +},\ +\ +fc0_trigger_start:fc_trigger_price.* {\ + my $fc_trigger_price = ReadingsVal("$NAME","fc_trigger_price",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;;\ + my $fc_total = 0;;\ +\ + for (my $loop_hour = $hour;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc0_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total < $fc_trigger_price ) {\ + return(sprintf("%02d:00",$loop_hour)) ;;\ + }\ + } # end for loop_hour\ +\ + return("null");;\ +},\ +\ +fc0_trigger_stop:fc0_trigger_start.* {\ + my $fc = 0;;\ + my $loop_hour = 0;;\ + my $fc_trigger_price = ReadingsVal("$NAME","fc_trigger_price",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my $fc_trigger_start = ReadingsVal("$NAME","fc0_trigger_start","null");;\ + my $fc_trigger_stop = $fc_trigger_start;;\ +\ + if ( $fc_trigger_start ne "null" ) {\ + $fc_trigger_start =~ /(\d\d):/;; $fc_trigger_start = $1 ;;\ + my $fc_total = 0;;\ +\ + for ($loop_hour = $fc_trigger_start;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc".$fc."_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total < $fc_trigger_price ) {\ + $fc_trigger_stop = sprintf("%02d:00",$loop_hour) ;;\ + } else {\ + return(sprintf("%02d:00",$loop_hour));;\ + }\ +\ + # wechsel zum nächsten Tag\ + if ( $loop_hour == 23 and $fc == 0 ) {\ + $fc = 1;;\ + $loop_hour = -1;;\ + }\ +\ + } # end for loop_hour\ + }\ + \ + return($fc_trigger_stop);;\ +},\ +\ +fc0_trigger:fc0_trigger_stop.* {\ +\ + # Setzen des Triggers für die aktuelle Stunde\ + if ( ReadingsVal("$NAME","current_price",100) < ReadingsVal("$NAME","fc_trigger_price",0) ) {\ + return("on")\ + } else {\ + return("off")\ + }\ +},\ +\ +fc1_trigger_start:fc_trigger_price.* {\ + if (ReadingsVal("$NAME","fc1_00_startsAt","null") ne "null") {\ + my $fc_trigger_price = ReadingsVal("$NAME","fc_trigger_price",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;;\ + my $fc_total = 0;;\ +\ + for (my $loop_hour = 0;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc1_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total < $fc_trigger_price ) {\ + return(sprintf("%02d:00",$loop_hour)) ;;\ + }\ + } # end for loop_hour\ + }\ + return("null");;\ +},\ +\ +fc1_trigger_stop:fc0_trigger_start.* {\ + my $loop_hour = 0;;\ + my $fc_trigger_price = ReadingsVal("$NAME","fc_trigger_price",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my $fc_trigger_start = ReadingsVal("$NAME","fc1_trigger_start","null");;\ + my $fc_trigger_stop = $fc_trigger_start;;\ +\ + if ( $fc_trigger_start ne "null" ) {\ + $fc_trigger_start =~ /(\d\d):/;; $fc_trigger_start = $1 ;;\ + my $fc_total = 0;;\ +\ + for ($loop_hour = $fc_trigger_start;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc1_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total < $fc_trigger_price ) {\ + $fc_trigger_stop = sprintf("%02d:00",$loop_hour) ;;\ + } else {\ + return(sprintf("%02d:00",$loop_hour));;\ + }\ +\ + } # end for loop_hour\ + }\ + \ + return($fc_trigger_stop);;\ +},\ +\ +fc_trigger_max:fc_avg.* {\ + my $fc_avg = ReadingsVal("$NAME","fc_avg",0);;\ + my $fc_max = ReadingsVal("$NAME","fc_max",0);;\ +\ + # Berechnung eines Schwellwertes als täglichen Maximalpreises\ + my $price_level = round( ($fc_max - $fc_avg)/2 + $fc_avg , 0);;\ + \ +$price_level;;\ +},\ +\ +fc0_trigger_max_start:fc_trigger_max.* {\ + my $fc_trigger_max = ReadingsVal("$NAME","fc_trigger_max",0) /100;;\ +\ + # Ermitteln des nächsten Trigger_max Fensters\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;;\ + my $fc_total = 0;;\ +\ + for (my $loop_hour = $hour;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc0_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total > $fc_trigger_max ) {\ + return(sprintf("%02d:00",$loop_hour)) ;;\ + }\ + } # end for loop_hour\ +\ + return("null");;\ +},\ +\ +fc0_trigger_max_stop:fc0_trigger_max_start.* {\ + my $fc = 0;;\ + my $loop_hour = 0;;\ + my $fc_trigger_max = ReadingsVal("$NAME","fc_trigger_max",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my $fc_trigger_max_start = ReadingsVal("$NAME","fc0_trigger_max_start","null");;\ + my $fc_trigger_max_stop = $fc_trigger_max_start;;\ +\ + if ( $fc_trigger_max_start ne "null" ) {\ + $fc_trigger_max_start =~ /(\d\d):/;; $fc_trigger_max_start = $1 ;;\ + my $fc_total = 0;;\ +\ + for ($loop_hour = $fc_trigger_max_start;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc".$fc."_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total > $fc_trigger_max ) {\ + $fc_trigger_max_stop = sprintf("%02d:00",$loop_hour) ;;\ + } else {\ + return(sprintf("%02d:00",$loop_hour));;\ + }\ +\ + # wechsel zum nächsten Tag\ + if ( $loop_hour == 23 and $fc == 0 ) {\ + $fc = 1;;\ + $loop_hour = -1;;\ + }\ +\ + } # end for loop_hour\ + }\ + \ + return($fc_trigger_max_stop);;\ +},\ +\ +fc0_trigger_max:fc0_trigger_max_stop.* {\ +\ + # Setzen des maximum Triggers für die aktuelle Stunde\ + if ( ReadingsVal("$NAME","current_price",0) > ReadingsVal("$NAME","fc_trigger_max",0) ) {\ + return("on")\ + } else {\ + return("off")\ + }\ +},\ +\ +fc1_trigger_max_start:fc_trigger_max.* {\ + if (ReadingsVal("$NAME","fc1_00_startsAt","null") ne "null") {\ + my $fc_trigger_max = ReadingsVal("$NAME","fc_trigger_max",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;;\ + my $fc_total = 0;;\ +\ + for (my $loop_hour = 0;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc1_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total > $fc_trigger_max ) {\ + return(sprintf("%02d:00",$loop_hour)) ;;\ + }\ + } # end for loop_hour\ + }\ + return("null");;\ +},\ +\ +fc1_trigger_max_stop:fc0_trigger_max_start.* {\ + my $loop_hour = 0;;\ + my $fc_trigger_max = ReadingsVal("$NAME","fc_trigger_max",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my $fc_trigger_max_start = ReadingsVal("$NAME","fc1_trigger_max_start","null");;\ + my $fc_trigger_max_stop = $fc_trigger_max_start;;\ +\ + if ( $fc_trigger_max_start ne "null" ) {\ + $fc_trigger_max_start =~ /(\d\d):/;; $fc_trigger_max_start = $1 ;;\ + my $fc_total = 0;;\ +\ + for ($loop_hour = $fc_trigger_max_start;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc1_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total > $fc_trigger_max ) {\ + $fc_trigger_max_stop = sprintf("%02d:00",$loop_hour) ;;\ + } else {\ + return(sprintf("%02d:00",$loop_hour));;\ + }\ +\ + } # end for loop_hour\ + }\ + \ + return($fc_trigger_max_stop);;\ +},\ +\ +total_cost_day:nodes_TIMESTAMP.* {\ +## Berechnung des Tages Wertes\ +::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT CAST(SUM(VALUE) AS DECIMAL(8,2)) AS VALUE\ + FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_cost'\ + AND date(TIMESTAMP) = curdate() ;;") ;;\ +},\ +\ +total_cost_month:nodes_TIMESTAMP.* {\ +## Berechnung des monats Wertes\ +::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT CAST(SUM(VALUE) AS DECIMAL(8,2)) AS VALUE\ + FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_cost'\ + AND YEAR(TIMESTAMP) = YEAR(curdate())\ + AND MONTH(TIMESTAMP) = MONTH(curdate()) ;;") ;;\ +},\ +\ +total_cost_year:nodes_TIMESTAMP.* {\ +## Berechnung des Jahres Wertes\ +::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + SELECT CAST(SUM(VALUE) AS DECIMAL(8,2)) AS VALUE\ + FROM history\ + WHERE DEVICE='".$NAME."'\ + AND READING='nodes_cost'\ + AND YEAR(TIMESTAMP) = YEAR(curdate()) ;;") ;;\ +},\ +\ +fc_DbLog:fc0_00_total.* {\ +my ($timestamp,$date,$hour,$value,$loop_fc_next) = 5x0;;\ +\ +for (my $loop_fc = 0;; $loop_fc <= 1;; $loop_fc++) {\ + $loop_fc_next = $loop_fc +1;;\ + $date = ReadingsVal("$NAME","fc".$loop_fc."_00_startsAt","null");;\ + if ($date ne "null") {\ + $date =~ /([\d+-]+)/;; $date = $1 ;;\ + for (my $loop_hour = 0;; $loop_hour <= 23;; $loop_hour++) {\ + $hour = sprintf("%02d",$loop_hour);;\ + $timestamp = $date." ".$hour.":00:00";;\ + $value = ReadingsVal("$NAME","fc".$loop_fc."_".$hour."_total","null");;\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$timestamp."','$NAME','Tibber','fc".$loop_fc."_total','".$value."')\ + ON DUPLICATE KEY UPDATE\ + VALUE='".$value."';;") ;;\ + }\ + if (ReadingsVal("$NAME","fc".$loop_fc."_00_startsAt","null") eq ReadingsVal("$NAME","fc".$loop_fc_next."_00_startsAt","null")) {\ + fhem("deletereading $NAME fc".$loop_fc_next."_.*");;\ + }\ + } else {\ + fhem("deletereading $NAME fc1_.*");;\ + }\ +}\ +ReadingsTimestamp("$NAME","fc0_00_startsAt","null");;\ +} +attr EVU_Tibber_connect verbose 0 +attr EVU_Tibber_connect ws_minInterval 54 +attr EVU_Tibber_connect ws_websocketURL wss:websocket-api.tibber.com:443/v1-beta/gql/subscriptions \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_LogDBRep_EVU_Tibber_connect_SQL.txt b/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_LogDBRep_EVU_Tibber_connect_SQL.txt new file mode 100644 index 000000000..e1d3df693 --- /dev/null +++ b/fhem/contrib/ch.eick/Strombörse/EVU_Tibber/RAW_LogDBRep_EVU_Tibber_connect_SQL.txt @@ -0,0 +1,5 @@ +defmod LogDBRep_EVU_Tibber_connect_SQL DbRep LogDB +attr LogDBRep_EVU_Tibber_connect_SQL DbLogExclude .* +attr LogDBRep_EVU_Tibber_connect_SQL room System +attr LogDBRep_EVU_Tibber_connect_SQL sqlCmdHistoryLength 5 +attr LogDBRep_EVU_Tibber_connect_SQL timeout 20 \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Strombörse/EVU_aWATTar/RAW_EVU_aWATTar.txt b/fhem/contrib/ch.eick/Strombörse/EVU_aWATTar/RAW_EVU_aWATTar.txt new file mode 100644 index 000000000..37ff97202 --- /dev/null +++ b/fhem/contrib/ch.eick/Strombörse/EVU_aWATTar/RAW_EVU_aWATTar.txt @@ -0,0 +1,191 @@ +defmod EVU_aWATTar_connect HTTPMOD https://api.awattar.de/v1/marketdata/current.yaml 0 +attr EVU_aWATTar_connect DbLogExclude .* +attr EVU_aWATTar_connect comment Version 2024.01.23 13:00\ +\ +Achtung, momentan werden nur die Börsenpreise ohne die fix Kosten dargestellt.\ +\ +https://api.awattar.de/v1/marketdata +attr EVU_aWATTar_connect enableControlSet 1 +attr EVU_aWATTar_connect get01-15Name fc_max +attr EVU_aWATTar_connect get01-15OExpr round(($val+$val*0.03+1.785)*1.19,2) +attr EVU_aWATTar_connect get01-1Name current_date +attr EVU_aWATTar_connect get01-22Name fc_med +attr EVU_aWATTar_connect get01-22OExpr round(($val+$val*0.03+1.785)*1.19,2) +attr EVU_aWATTar_connect get01-29Name fc_avg +attr EVU_aWATTar_connect get01-29OExpr round(($val+$val*0.03+1.785)*1.19,2) +attr EVU_aWATTar_connect get01-36Name current_price +attr EVU_aWATTar_connect get01-36OExpr round(($val+$val*0.03+1.785)*1.19,2) +attr EVU_aWATTar_connect get01-8Name fc_min +attr EVU_aWATTar_connect get01-8OExpr round(($val+$val*0.03+1.785)*1.19,2) +attr EVU_aWATTar_connect get01Name 01_priceInfo +attr EVU_aWATTar_connect get01RegOpt g +attr EVU_aWATTar_connect get01Regex date_now: (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})|price_low: ([0-9]+[0-9\.]+)|price_high: ([0-9]+[0-9\.]+)|price_median: ([0-9]+[0-9\.]+)|price_average: ([0-9]+[0-9\.]+)|price_current: ([0-9]+[0-9\.]+) +attr EVU_aWATTar_connect get01URL https://api.awattar.de/v1/marketdata/current.yaml +attr EVU_aWATTar_connect get02-10Name fc0_09_total +attr EVU_aWATTar_connect get02-10OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-11Name fc0_10_total +attr EVU_aWATTar_connect get02-11OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-12Name fc0_11_total +attr EVU_aWATTar_connect get02-12OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-13Name fc0_12_total +attr EVU_aWATTar_connect get02-13OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-14Name fc0_13_total +attr EVU_aWATTar_connect get02-14OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-15Name fc0_14_total +attr EVU_aWATTar_connect get02-15OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-16Name fc0_15_total +attr EVU_aWATTar_connect get02-16OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-17Name fc0_16_total +attr EVU_aWATTar_connect get02-17OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-18Name fc0_17_total +attr EVU_aWATTar_connect get02-18OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-19Name fc0_18_total +attr EVU_aWATTar_connect get02-19OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-1Name fc0_00_total +attr EVU_aWATTar_connect get02-1OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-20Name fc0_19_total +attr EVU_aWATTar_connect get02-20OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-21Name fc0_20_total +attr EVU_aWATTar_connect get02-21OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-22Name fc0_21_total +attr EVU_aWATTar_connect get02-22OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-23Name fc0_22_total +attr EVU_aWATTar_connect get02-23OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-24Name fc0_23_total +attr EVU_aWATTar_connect get02-24OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-2Name fc0_01_total +attr EVU_aWATTar_connect get02-2OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-3Name fc0_02_total +attr EVU_aWATTar_connect get02-3OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-4Name fc0_03_total +attr EVU_aWATTar_connect get02-4OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-5Name fc0_04_total +attr EVU_aWATTar_connect get02-5OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-6Name fc0_05_total +attr EVU_aWATTar_connect get02-6OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-7Name fc0_06_total +attr EVU_aWATTar_connect get02-7OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-8Name fc0_07_total +attr EVU_aWATTar_connect get02-8OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02-9Name fc0_08_total +attr EVU_aWATTar_connect get02-9OExpr round(($val+$val*0.03+1.785)*1.19/100,4) +attr EVU_aWATTar_connect get02FollowGet 01_priceInfo +attr EVU_aWATTar_connect get02Name 02_priceDay +attr EVU_aWATTar_connect get02RegOpt g +attr EVU_aWATTar_connect get02Regex (?<=abs_[0-9]{2}_amount: )([0-9]+[0-9\.]+) +attr EVU_aWATTar_connect get02URL https://api.awattar.de/v1/marketdata/current.yaml +attr EVU_aWATTar_connect get03-1Name fc3_00_startsAt +attr EVU_aWATTar_connect get03-1OExpr POSIX::strftime("%Y-%m-%d %H:%M:%S",localtime(substr($val,0,10))) +attr EVU_aWATTar_connect get03-4Name fc3_00_total +attr EVU_aWATTar_connect get03-4OExpr round($val/1000,4) +attr EVU_aWATTar_connect get03Name 02_priceAll +attr EVU_aWATTar_connect get03RegOpt g +attr EVU_aWATTar_connect get03Regex "start_timestamp": (\d{10})|"marketprice": (\d*\.\d*) +attr EVU_aWATTar_connect get03URL https://api.awattar.de/v1/marketdata?start=1701990000000&end=1702159200000 +attr EVU_aWATTar_connect group PV Steuerung EVU +attr EVU_aWATTar_connect icon sani_pump +attr EVU_aWATTar_connect room Strom->Boerse +attr EVU_aWATTar_connect sortby 213 +attr EVU_aWATTar_connect userReadings fc_trigger_price:fc_avg.* {\ +## fc_trigger_price:[fc_avg|compensation_grid].* {\\ + my $fc_avg = ReadingsVal("$NAME","fc_avg",0);;\ + my $fc_min = ReadingsVal("$NAME","fc_min",0);;\ +\ + # Berechnung eines Default Schwellwertes als täglicher Niedrigpreis\ + my $price_level = round( ($fc_avg - $fc_min)/2 + $fc_min , 1);;\ + \ + # Abschätzung von Wirtschaftlichkeit beim Speicher Laden, falls Tibber zu teuer wird\ + if ( ReadingsVal("$NAME","compensation_grid",0) != 0 ) {\ + my $price_level_battery = round( ($fc_avg - ReadingsVal("$NAME","compensation_grid",0)) *0.85 , 1) ;;\ + if ( $price_level > $price_level_battery ) {\ + $price_level = $price_level_battery;;\ + }\ + }\ + $price_level;;\ +},\ +\ +fc0_trigger_start:fc_trigger_price.* {\ + my $fc_trigger_price = ReadingsVal("$NAME","fc_trigger_price",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;;\ + my $fc_total = 0;;\ +\ + for (my $loop_hour = $hour;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc0_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total < $fc_trigger_price ) {\ + return(sprintf("%02d:00",$loop_hour)) ;;\ + }\ + } # end for loop_hour\ +\ + return("null");;\ +},\ +\ +fc0_trigger_stop:fc0_trigger_start.* {\ + my $fc = 0;;\ + my $loop_hour = 0;;\ + my $fc_trigger_price = ReadingsVal("$NAME","fc_trigger_price",0) /100;;\ +\ + # Ermitteln des nächsten Trigger Fensters\ + my $fc_trigger_start = ReadingsVal("$NAME","fc0_trigger_start","null");;\ + my $fc_trigger_stop = $fc_trigger_start;;\ +\ + if ( $fc_trigger_start ne "null" ) {\ + $fc_trigger_start =~ /(\d\d):/;; $fc_trigger_start = $1 ;;\ + my $fc_total = 0;;\ +\ + for ($loop_hour = $fc_trigger_start;; $loop_hour <= 23;; $loop_hour++) {\ + $fc_total = ReadingsVal("$NAME","fc".$fc."_".sprintf("%02d",$loop_hour)."_total",0);;\ + if ( $fc_total < $fc_trigger_price ) {\ + $fc_trigger_stop = sprintf("%02d:00",$loop_hour) ;;\ + } else {\ + return(sprintf("%02d:00",$loop_hour));;\ + }\ +\ + # wechsel zum nächsten Tag\ + if ( $loop_hour == 23 and $fc == 0 ) {\ + $fc = 1;;\ + $loop_hour = -1;;\ + }\ +\ + } # end for loop_hour\ + }\ + \ + return($fc_trigger_stop);;\ +},\ +\ +fc0_trigger:fc0_trigger_stop.* {\ +\ + # Setzen des Triggers für die aktuelle Stunde\ + if ( ReadingsVal("$NAME","current_price",100) < ReadingsVal("$NAME","fc_trigger_price",0) ) {\ + return("on")\ + } else {\ + return("off")\ + }\ +},\ +\ +fc_DbLog:fc0_00_total.* {\ +my ($timestamp,$date,$hour,$value,$loop_fc_next) = 5x0;;\ +\ +for (my $loop_fc = 0;; $loop_fc <= 1;; $loop_fc++) {\ + $loop_fc_next = $loop_fc +1;;\ + $date = ReadingsVal("$NAME","current_date","null");;\ + if ($date ne "null") {\ + $date =~ /([\d+-]+)/;; $date = $1 ;;\ + for (my $loop_hour = 0;; $loop_hour <= 23;; $loop_hour++) {\ + $hour = sprintf("%02d",$loop_hour);;\ + $timestamp = $date." ".$hour.":00:00";;\ + $value = ReadingsVal("$NAME","fc".$loop_fc."_".$hour."_total","null");;\ + ::CommandGet(undef, "LogDBRep_".$NAME."_SQL sqlCmdBlocking\ + INSERT INTO history (TIMESTAMP,DEVICE,TYPE,READING,VALUE)\ + VALUES('".$timestamp."','$NAME','Tibber','fc".$loop_fc."_total','".$value."')\ + ON DUPLICATE KEY UPDATE\ + VALUE='".$value."';;") ;;\ + }\ + } else {\ + fhem("deletereading $NAME fc1_.*");;\ + }\ +}\ +ReadingsVal("$NAME","current_date","null");;\ +} +attr EVU_aWATTar_connect verbose 0 \ No newline at end of file diff --git a/fhem/contrib/ch.eick/Strombörse/EVU_aWATTar/RAW_LogDBRep_EVU_aWATTar_connect_SQL.txt b/fhem/contrib/ch.eick/Strombörse/EVU_aWATTar/RAW_LogDBRep_EVU_aWATTar_connect_SQL.txt new file mode 100644 index 000000000..d6eb31ddf --- /dev/null +++ b/fhem/contrib/ch.eick/Strombörse/EVU_aWATTar/RAW_LogDBRep_EVU_aWATTar_connect_SQL.txt @@ -0,0 +1,5 @@ +defmod LogDBRep_EVU_aWATTar_connect_SQL DbRep LogDB +attr LogDBRep_EVU_aWATTar_connect_SQL DbLogExclude .* +attr LogDBRep_EVU_aWATTar_connect_SQL room System +attr LogDBRep_EVU_aWATTar_connect_SQL sqlCmdHistoryLength 5 +attr LogDBRep_EVU_aWATTar_connect_SQL timeout 20 \ No newline at end of file