OpenWB: Unterschied zwischen den Versionen
(18 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
==Integration OpenWB in FHEM== | == Integration der openWB in FHEM - Ladeleistung anzeigen und Umschalten des Lademodus == | ||
Ausgangssituation ist ein funktionierendes FHEM, ohne weitere Vorbedingungen.<syntaxhighlight lang="perl"> | |||
defmod openwb MQTT <openWBip>:1883 | |||
attr openwb room Auto,MQTT | |||
</syntaxhighlight>Dadurch wird der MQTT-Server der openWB angesprochen, FHEM ist der Client. | |||
Ein Ladepunkt wird als MQTT_Device angelegt:<syntaxhighlight lang="perl"> | |||
defmod lp1 MQTT_DEVICE | |||
attr lp1 IODev openwb | |||
attr lp1 publishSet_chargeMode openWB/set/ChargeMode | |||
attr lp1 room Auto,Dashboard,MQTT | |||
attr lp1 stateFormat power | |||
attr lp1 subscribeReading_chargeMode openWB/global/ChargeMode | |||
attr lp1 subscribeReading_plugStat openWB/lp/1/boolPlugStat | |||
attr lp1 subscribeReading_power openWB/lp/1/W | |||
</syntaxhighlight>Die Umsetzung basiert auf openWB 1.9.x, der Lademodus "ChargeMode" gilt hier noch global für alle Ladepunkte. | |||
Beispielhaft die Definition des zweiten Ladepunktes, eine zweite openWB, die als "nur Ladepunkt" mit der angesprochenen openWB verbunden ist. | |||
Eine openWB kann derzeit 8 Ladepunkte verwalten, die Nummern müssen entsprechend inkrementiert werden.<syntaxhighlight lang="perl"> | |||
defmod lp2 MQTT_DEVICE | |||
attr lp2 IODev openwb | |||
attr lp2 publishSet_chargeMode openWB/set/ChargeMode | |||
attr lp2 room Auto,Dashboard,MQTT | |||
attr lp2 stateFormat power | |||
attr lp2 subscribeReading_chargeMode openWB/global/ChargeMode | |||
attr lp2 subscribeReading_plugStat openWB/lp/2/boolPlugStat | |||
attr lp2 subscribeReading_power openWB/lp/2/W | |||
</syntaxhighlight>Die MQTT-Topics zum Lesen und Schreiben von Werten sind ganz unten auf dieser Wiki-Seite zu finden. | |||
Die Einbindung in die TabletUI sieht bei mir so aus: | |||
[[Datei:Ladepunkte in TabletUI.png|alternativtext=Darstellung der openWB Ladepunkte in der TabletUI|mini|488x488px|Beispielhafte Darstellung in der TabletUI]] | |||
[[Datei:Auswahl des Lademodus.png|alternativtext=Darstellung der openWB Ladepunkte in der TabletUI - Auswahl des Lademodus|mini|486x486px|Auswahl des Lademodus per CircleMenu]] | |||
<syntaxhighlight lang="html"> | |||
<div class="cell-60 left-space right-space"> | |||
<div data-type="symbol" data-icon="fa-car" class="tall compressed" data-color="lightgray"> | |||
<div data-type="circlemenu" data-direction="full" class="mini" style="top: -0.5em;"> | |||
<ul class="mini"> | |||
<li><div data-type="push" data-device="lp1" data-get="chargeMode" data-states='[0,1,2,3,4]' data-colors='["lightgreen","greenyellow","yellow","grey","black"]' data-icons='["fa-bolt","fa-plus-circle","fa-sun-o","fa-pause-circle-o","fa-stop-circle-o"]' data-background-icon=""></div></li> | |||
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="0" data-get-on="0" data-icon="fa-bolt" data-color="lightgreen" data-background-icon=""></div></li> | |||
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="1" data-get-on="1" data-icon="fa-plus-circle" data-color="greenyellow" data-background-icon=""></div></li> | |||
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="2" data-get-on="2" data-icon="fa-sun-o" data-color="yellow" data-background-icon=""></div></li> | |||
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="3" data-get-on="3" data-icon="fa-pause-circle-o" data-color="grey" data-background-icon=""></div></li> | |||
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="4" data-get-on="4" data-icon="fa-stop-circle-o" data-color="black" data-background-icon=""></div></li> | |||
</ul> | |||
</div> | |||
<div style="font-size: 30% !important;" class="mini " data-pre-text="" data-type="label" data-device="lp1" data-get="power" data-unit="" data-factor="1" data-fix="0"></div> | |||
<div data-type="symbol" data-device="lp1" data-get="plugStat" data-states='[0,1]' data-colors='["white","black"]' data-icons='["","fa-plug"]' data-background-icon="" class="mini" style="font-size: 30% !important; top:1em;"></div></li> | |||
</div> | |||
</div> | |||
</syntaxhighlight> | |||
==Integration OpenWB in FHEM - Übertragung von EVU, PV und Batteriewerten an openWB== | |||
Ausgangssituation ist ein funktionierendes FHEM-System, bei dem bereits der digitale Stromzähler ("Moderne Meßeinrichtung") über das Modul 47_OBIS und der PV-Wechselrichter über ein entsprechendes Modul, z.B. ModbusAttr integriert sind. Als OpenWB-System wurde hier eine reale OpenWB-Wallbox angebunden. | Ausgangssituation ist ein funktionierendes FHEM-System, bei dem bereits der digitale Stromzähler ("Moderne Meßeinrichtung") über das Modul 47_OBIS und der PV-Wechselrichter über ein entsprechendes Modul, z.B. ModbusAttr integriert sind. Als OpenWB-System wurde hier eine reale OpenWB-Wallbox angebunden. | ||
Zeile 53: | Zeile 107: | ||
==Anwendungs Beispiele== | ==Anwendungs Beispiele== | ||
===Komplexe Anbindung=== | ===Komplexe Anbindung=== | ||
[[Bild:Kia.PNG|mini| | [[Bild:Kia.PNG|mini|700px|rechts|WallBox mit Kia Fahrzeug]] | ||
Hier mal ein Beispiel mit weiteren Schnittstellen in der Haussteuerung. Im Hintergrund arbeitet ein Wechselrichter Schwarm mit einem Hausspeicher, der beim BEV Laden gesperrt wird. Die openWB kommuniziert direkt mit den zwei Kostal Wechselrichtern, dem KSEM und dem am Master angeschlossenen Speicher. Das BEV ist über Kia Connect angebunden. | Hier mal ein Beispiel mit weiteren Schnittstellen in der Haussteuerung. Im Hintergrund arbeitet ein Wechselrichter Schwarm mit einem Hausspeicher, der beim BEV Laden gesperrt wird. Die openWB kommuniziert direkt mit den zwei Kostal Wechselrichtern, dem KSEM und dem am Master angeschlossenen Speicher. Das BEV ist über Kia Connect angebunden. | ||
[[Bild:WB_1.PNG|mini|700px|rechts|openWB mit Statistiken]] | |||
[[Bild:Kostal Flow.PNG|mini|700px|rechts|Sowas könnte am Schluss, inklusive Wechselrichter, raus kommen. Die openWBs sind unten links.]] | [[Bild:Kostal Flow.PNG|mini|700px|rechts|Sowas könnte am Schluss, inklusive Wechselrichter, raus kommen. Die openWBs sind unten links.]] | ||
====Verwendete Schnittstellen / Devices==== | ====Verwendete Schnittstellen / Devices==== | ||
=====openWB MQTT===== | =====openWB MQTT===== | ||
Wie oben beschrieben mit folgender MQTT definition | Wie oben beschrieben mit folgender MQTT definition. Im Bild ist das DOIF dargestellt und das MQTT Device als kurze Darstellung unterhalb der Tabelle. Das MQTT wird nur zur Kopplung verwendet, hat jedoch jetzt auch ein stateFormat inklusieve Statistiken erhalten. | ||
RAW des MQTT Device | RAW des MQTT Device | ||
<syntaxhighlight lang="Perl"> | <syntaxhighlight lang="Perl"> | ||
defmod | defmod WB_1 MQTT2_DEVICE WB_1_MQTT2 | ||
attr | attr WB_1 DbLogExclude .* | ||
attr | attr WB_1 DbLogInclude lp_1_.*,.*AllChargePoints.*,ChargeMode | ||
attr | attr WB_1 IODev WB_1_MQTT2 | ||
attr | attr WB_1 alias WB_1 | ||
attr | attr WB_1 autocreate 0 | ||
attr | attr WB_1 comment Die openWB besteht aus zwei Ladepunkten. | ||
attr | attr WB_1 devicetopic openWB | ||
attr | attr WB_1 disable 0 | ||
attr | attr WB_1 event-on-change-reading lp_1_.*,.*AllChargePoints.*,ChargeMode | ||
$DEVICETOPIC/ | attr WB_1 group PV Eigenverbrauch | ||
$DEVICETOPIC/ | attr WB_1 icon fuel | ||
$DEVICETOPIC/ | attr WB_1 readingList $DEVICETOPIC/global/WHouseConsumption:.* WHouseConsumption\ | ||
$DEVICETOPIC/ | $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\ | |||
attr | $DEVICETOPIC/global/cpuTemp:.* cpuTemp\ | ||
attr | \ | ||
$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/faultState:.* lp_2_faultState\ | |||
$DEVICETOPIC/set/lp/2/faultStr:.* lp_2_faultStr\ | |||
$DEVICETOPIC/set/lp/2/ChargePointEnabled:.* lp_2_ChargePointEnabled | |||
attr WB_1 room MQTT2_DEVICE,Strom->Photovoltaik | |||
attr WB_1 setList Lademodus:SofortLaden,Min+PV,NurPV,Stop,Standby { my %h=(SofortLaden=>'0','Min+PV'=>'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) } | |||
attr WB_1 sortby 311 | |||
attr WB_1 stateFormat {\ | |||
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")? "<span style='color:red'>SofortLaden</span>" : ($ChargeMode eq "MinPV")? "<span style='color:orange'>Min+PV</span>" : ($ChargeMode eq "NurPV")? "<span style='color:green'>NurPV</span>" : $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")."<br>".ReadingsVal($name,"lp_1_ChargeStat","n/a");;\ | |||
my $lp_1_Status_2 = ReadingsVal($name,"lp_1_TimeRemaining","n/a");;\ | |||
\ | |||
my $lp_1_Power_d = ReadingsVal($name,"lp_1_kWhDailyCharged",0)." kWh";;\ | |||
my $lp_1_Power_m = round(ReadingsVal($name,"lp_1_kWhCounter_Month",0),0)." kWh";;\ | |||
my $lp_1_Power_j = sprintf("%04d / %04d",ReadingsVal($name,"lp_1_kWhCounter_Year",0),ReadingsVal($YearBefore,"lp_1_kWhCounter_Year",0));;\ | |||
my $lp_1_Power_t = round(ReadingsVal($name,"lp_1_kWhCounter",0),0)." kWh";;\ | |||
\ | |||
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")."<br>".ReadingsVal($name,"lp_2_ChargeStat","n/a");;\ | |||
my $lp_2_Status_2 = "<br>".ReadingsVal($name,"lp_2_TimeRemaining","n/a");;\ | |||
\ | |||
my $lp_2_Power_d = ReadingsVal($name,"lp_2_kWhDailyCharged",0)." kWh";;\ | |||
my $lp_2_Power_m = round(ReadingsVal($name,"lp_2_kWhCounter_Month",0),0)." kWh";;\ | |||
my $lp_2_Power_j = sprintf("%04d / %04d",ReadingsVal($name,"lp_2_kWhCounter_Year",0),ReadingsVal($YearBefore,"lp_2_kWhCounter_Year",0));;\ | |||
my $lp_2_Power_t = round(ReadingsVal($name,"lp_2_kWhCounter",0),0)." kWh";;\ | |||
\ | |||
"<html><table border=2 bordercolor='darkgreen' cellspacing=0 style='width: 100%'>\ | |||
<colgroup>\ | |||
<col span='1' style='width: 52%;;'>\ | |||
<col span='1' style='width: 12%;;'>\ | |||
<col span='1' style='width: 12%;;'>\ | |||
<col span='1' style='width: 12%;;'>\ | |||
<col span='1' style='width: 12%;;'>\ | |||
</colgroup>\ | |||
<tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'>Wallbox</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>$ChargeMode</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Status</td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'>Restladezeit</td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'>Leistung</td></tr>\ | |||
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'> ; ;".$lp_1_Name."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Status_1."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Status_2."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power_1."<br>".$lp_1_Power."</td></tr>\ | |||
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'> ; ;".$lp_2_Name."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Status_1."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Status_2."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power_1."<br>".$lp_2_Power."</td></tr>\ | |||
<tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'>Statistik vom $date</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>aktuell</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Heute</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Monat</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Jahr/Vorjahr</td></tr>\ | |||
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'> ; ;".$lp_1_Name."<td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power_d."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power_m."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power_j."</td></tr>\ | |||
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'> ; ;".$lp_2_Name."<td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power_d."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power_m."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power_j."</td></tr>\ | |||
</table>\ | |||
</html>"\ | |||
} | |||
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) } | |||
</syntaxhighlight> | </syntaxhighlight> | ||
===== | =====Kia connect MQTT===== | ||
Das Kia_connect Device empfängt und sendet die MQTT Nachrichten zum Node-red Flow für das Kia BEV. | |||
RAW des Kia connect | |||
<syntaxhighlight lang="Perl"> | <syntaxhighlight lang="Perl"> | ||
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 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/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 | |||
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);;;;} | |||
</syntaxhighlight> | |||
=====Node-red===== | |||
[[Bild:Kia Flow.PNG|mini|900px|rechts|Node-red Kia Flow]] | |||
Node-red habe ich einfach in einem Docker Container runter geladen und gestartet. Über Port 1880 kommt man direkt in die GUI und kann den ersten Flow laden. | |||
Weiterhin sollte man darauf achten, dass man nur eine begrenzte Anzahl von Nachrichten mit dem Kia BEV pro Tag austauschen kann. Das wurde im DOIF schon etwas berücksichtigt (1x pro Stunde), kann jedoch bei gleichzeitiger Verwendung der Handy App oder der SOC Abfrage im openWB Kia Modul auch mal zu Fehlern führen. Durch die Stündliche Status Abfrage im DOIF kommt es natürlich zu Verzögerungen im FHEM Status. Dann einfach einmal Manuell abfragen. | docker-compose .yml Eintrag | ||
<syntaxhighlight lang="Perl"> | |||
node-red: | |||
image: nodered/node-red:latest | |||
restart: always | |||
environment: | |||
- TZ=Europe/Berlin | |||
ports: | |||
- 1880:1880 | |||
volumes: | |||
- ./node-red/data:/data | |||
</syntaxhighlight> | |||
Danach fehlt im Container noch folgende Erweiterung für den Node-red Flow | |||
<syntaxhighlight lang="Perl"> | |||
npm install node-red-contrib-bluelinky | |||
</syntaxhighlight> | |||
=====Kia Connect===== | |||
<pre> | |||
Kia connect ist eine API für Kia und Hyundai E-Autos mit der man Daten vom Auto abfragen kann und auch einige Steuerungen möglich sind. | |||
Mit Node-red und BlueLinky wird die Schnittstelle bedient. | |||
Der Flow ist nicht ursprünglich von mir, wurde jedoch noch erweitert. | |||
Vor dem Laden des Flows sind noch die persönlichen Verbindungsdaten im JSON einzutragen. | |||
Nach dem Laden ist ein Test mit den Inject Symbolen und der Debug Funktionalität möglich und auch sinnvoll. | |||
Unterhalb der MQTT - und BlueLinky Symbole sollte "Verbunden" oder "Ready" erscheinen. | |||
</pre> | |||
'''Wichtig beim Kia ist, dass für das Laden über die openWB als SOC Ziel 80% im standard Modus konfiguriert wird.''' Ansonsten wundert man sich warum das Laden einfach nicht starten möchte. Im Default ist dort bei mir nur 50% eingetragen gewesen :-). Mit jetzt 100% kann die openWB auch selber einen Ziel SOC bestimmen, ansonsten hört das BEV einfach selber auf zu laden. | |||
Weiterhin sollte man darauf achten, dass man nur eine begrenzte Anzahl von Nachrichten mit dem Kia BEV pro Tag austauschen kann. Das wurde im DOIF schon etwas berücksichtigt (1x pro Stunde), kann jedoch bei gleichzeitiger Verwendung der Handy App oder der SOC Abfrage im openWB Kia Modul auch mal zu Fehlern führen. Durch die Stündliche Status Abfrage im DOIF kommt es natürlich zu Verzögerungen im FHEM Status. Dann einfach einmal Manuell abfragen. | |||
Node-red JSON Import | Node-red JSON Import | ||
Zeile 1.352: | Zeile 1.673: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
===== | =====Kia_eNiro_PV DOIF mit uiTable===== | ||
Mit diesem DOIF Device werden folgende Funktionalitäten abgebildet: | |||
Nun dann noch das DOIF mit dem uiTable für die Status Anzeige und die Steuerung über Pull Down Menüs. | |||
- Status Abfrage | |||
Status jede Stunde zwischen 6 und 23 Uhr (12V min 40%) | |||
Status beim Laden alle 15 Minuten (12V min 40%) | |||
Anzeige des Kilometerzählers | |||
Status des Fahrzeuges zu Hause / unterwegs und beim Laden | |||
Fahrzeug Auf/Zu | |||
Achtung, die Kia connect Abfragen sind auf ca. 200 pro | - Klimatisierung über das Pull Down Menü | ||
unterschiedliche Temperaturen für Heizen und Kühlen | |||
Aktuelle Temperatur | |||
Heizen/Klima Ein/Aus | |||
Timer für zeitgesteuertes Klimatisieren für den Resttag oder den Nächsten Tag (vor der aktuellen Zeit) | |||
Klimatisierung über "Abfall" Kalender (es geht nur ein Termin pro Tag, dafür aber komfortabel über das Handy) | |||
- Komfort | |||
Reifen Überwachung | |||
Türen / Motorhaube / Kofferraum Überwachung | |||
12V Batterie anzeige, wenn der Ladezustand kleiner 40% ist erfolgt keine weitere Status Abfrage | |||
- ACCU Steuerung | |||
Setzen des Ziel SOC beim Standard Laden | |||
Start/Stop Laden | |||
Accu Stand und berechnete Restkilometer | |||
- Für openWB integratin im uiTable | |||
Wählen des Lademodus | |||
Vorrang EV oder Bat | |||
Sperren des Hausspeichers entweder manuell oder automatisch beim Laden. Der vorherige Zustand wird gespeichert | |||
Die Freigabe erfolgt über die Wechselrichter Implementierung, siehe dort [[Kostal_Plenticore_10_Plus#Externe_Speichersteuerung_.28ExternControl.29|"Externe Speicher Steuerung"]] | |||
Geschätzte Ladezeit | |||
Status Ladepunkt (Plug und Laden) | |||
Lade Status Phasen und Leistung | |||
'''Achtung, die Kia connect Abfragen sind auf ca. 200 pro Tag von Kia limitiert! Durch die Stündliche Status Abfrage im DOIF kommt es natürlich zu Verzögerungen im FHEM Status. Dann einfach einmal manuell abfragen.''' | |||
Die Kommunikation zum Kia BEV ist manchmal sehr träge, z.B. kann eine Status Abfrage auch mal 3 Minuten dauern, deshalb wurde eine Verriegelung implementiert. Es wird ein Status pending/idle angezeigt. Nur wenn der Zustand "idel" ist, können weitere Abfragen gestartet werden. Läuft z.B. die Status Abfrage kann man ein weiteres Kommando anstarten, es wird jedoch erst abgesetzt, wenn das vorherige Kommando fertig ist. Solange bleibt im Pull Down Menü das neue Kommando stehen. | |||
RAW des DOIF | RAW des DOIF | ||
Zeile 1.385: | Zeile 1.726: | ||
[Kia_connect:atHomeStanding] eq "true" and ## wenn das Auto zuhause ist\ | [Kia_connect:atHomeStanding] eq "true" and ## wenn das Auto zuhause ist\ | ||
[Kia_connect:charging] eq "true" or ## und es geladen wird\ | [Kia_connect:charging] eq "true" or ## und es geladen wird\ | ||
[:58] | [:58] and [05:00-23:00] ## ansonsten nur jede Stunde\ | ||
) and [Kia_connect:bat12v] > 40 ## aber die 12V Batterie sollte noch genügend Ladung haben\ | ) and [Kia_connect:bat12v] > 40 ## aber die 12V Batterie sollte noch genügend Ladung haben\ | ||
or [$SELF:cmd_event] eq "set_cmd_1" ## Das reagiert auf den Aufruf mit "set <Device> cmd_*"\ | or [$SELF:cmd_event] eq "set_cmd_1" ## Das reagiert auf den Aufruf mit "set <Device> cmd_*"\ | ||
Zeile 1.534: | Zeile 1.875: | ||
or [$SELF:ui_command_4] eq "Stop"\ | or [$SELF:ui_command_4] eq "Stop"\ | ||
or [$SELF:ui_command_4] eq "Standby"\ | or [$SELF:ui_command_4] eq "Standby"\ | ||
or [$SELF:ui_command_4] eq "Vorrang_EV"\ | |||
or [$SELF:ui_command_4] eq "Vorrang_Bat"\ | |||
)\ | )\ | ||
) {\ | ) {\ | ||
set_Reading("ui_command_before_4",[$SELF:ui_command_4]);;\ | set_Reading("ui_command_before_4",[$SELF:ui_command_4]);;\ | ||
\ | \ | ||
fhem_set("WB_1 Lademodus ".[$SELF:ui_command_4]);;\ | 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 7_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 7_WB_1_lp_1 : Lademodus ".[$SELF:ui_command_4]};;\ | |||
}\ | |||
\ | \ | ||
set_Reading("ui_command_4","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ | set_Reading("ui_command_4","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ | ||
Zeile 1.562: | Zeile 1.915: | ||
[WR_1_API:Battery_InternControl_MinHomeConsumption] eq "30000" ) {\ | [WR_1_API:Battery_InternControl_MinHomeConsumption] eq "30000" ) {\ | ||
set_Reading("WR_1_Speicher_1_ExternControl_smart_laden_before","aktiv");;\ | set_Reading("WR_1_Speicher_1_ExternControl_smart_laden_before","aktiv");;\ | ||
if (AttrVal("$SELF","verbose",0) >= 0)\ | |||
{Log 3, "$SELF 8_Speicher_sperren : smart_laden_before aktiv"};;\ | |||
} else {\ | } else {\ | ||
set_Reading("WR_1_Speicher_1_ExternControl_smart_laden_before","inaktiv");;\ | set_Reading("WR_1_Speicher_1_ExternControl_smart_laden_before","inaktiv");;\ | ||
if (AttrVal("$SELF","verbose",0) >= 0)\ | |||
{Log 3, "$SELF 8_Speicher_sperren : smart_laden_before inaktiv"};;\ | |||
}\ | }\ | ||
\ | \ | ||
Zeile 1.573: | Zeile 1.930: | ||
set_Reading("ui_command_4","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ | set_Reading("ui_command_4","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ | ||
## kann das Kommando nicht sofort wiederholt werden\ | ## 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]);;\ | |||
}\ | |||
}\ | |||
}\ | }\ | ||
} | } | ||
attr Kia_eNiro_PV DbLogExclude .* | attr Kia_eNiro_PV DbLogExclude .* | ||
attr Kia_eNiro_PV disable 0 | |||
attr Kia_eNiro_PV group PV Eigenverbrauch-Steuerung | attr Kia_eNiro_PV group PV Eigenverbrauch-Steuerung | ||
attr Kia_eNiro_PV icon car | attr Kia_eNiro_PV icon car | ||
Zeile 1.640: | Zeile 2.019: | ||
$ret = '<span style="color:red">Tür offen<br>';;\ | $ret = '<span style="color:red">Tür offen<br>';;\ | ||
if ($VL == 1){$ret.=' /VL'};;\ | if ($VL == 1){$ret.=' /VL'};;\ | ||
if ($VR == 1){$ret.=' /VR'};;\ | if ($VR == 1){$ret.=' /VR'};;\ | ||
if ($HL == 1){$ret.=' /HL'};;\ | if ($HL == 1){$ret.=' /HL'};;\ | ||
if ($HR == 1){$ret.=' /HR'};;\ | if ($HR == 1){$ret.=' /HR'};;\ | ||
$ret = $ret.'</span>';;\ | $ret = $ret.'</span>';;\ | ||
}\ | }\ | ||
if (::ReadingsVal($car,"status_trunkOpen","true") eq "true") {\ | if (::ReadingsVal($car,"status_trunkOpen","true") eq "true") {\ | ||
$ret.='<span style="color:red"> Kofferraum offen</span>';;\ | $ret.='<span style="color:red"> Kofferraum offen</span>';;\ | ||
}\ | }\ | ||
if (::ReadingsVal($car,"status_hoodOpen","true") eq "true") {\ | if (::ReadingsVal($car,"status_hoodOpen","true") eq "true") {\ | ||
$ret.='<span style="color:red"> Motorhaube offen</span>';;\ | $ret.='<span style="color:red"> Motorhaube offen</span>';;\ | ||
}\ | }\ | ||
return $ret;;\ | return $ret;;\ | ||
}\ | }\ | ||
}\ | }\ | ||
\ | \ | ||
"$SELF"|"Kommando ".::ReadingsTimestamp("Kia_connect","status_time","")."<dd>Auswahl / Kommunikation / Tacho / Info Status</dd>" | widget([$SELF:ui_command_1],"uzsuDropDown,---,Status_getAll,car_lock,car_unlock")|(([Kia_connect:req_active] eq "idle")?'<span style="color:green">idle</span>' : '<span style="color:red">'.[Kia_connect:req_active].'</span>') |::round([Kia_connect:odometer_value],0)." km"|FUNC_Status_Laden("Kia_connect")\ | "$SELF"|"Kommando ".::ReadingsTimestamp("Kia_connect","status_time","")."<dd>Auswahl / Kommunikation / Tacho / Info Status</dd>" | widget([$SELF:ui_command_1],"uzsuDropDown,---,Status_getAll,car_lock,car_unlock")|(([Kia_connect:req_active] eq "idle")?'<span style="color:green">idle</span>' : '<span style="color:red">'.[Kia_connect:req_active].'</span>') |::round([Kia_connect:odometer_value],0)." km"|FUNC_Status_Laden("Kia_connect")\ | ||
\ | \ | ||
|"Accu<dd>Steuerung / Target Soc / Accu Status</dd>" |widget([$SELF:ui_command_3],"uzsuDropDown,---,setChargeTargetSoc,stopCharge,startCharge")|"Target SOC".widget([Kia_connect:status_evStatus_reservChargeInfos_targetSOClist_2_targetSOClevel_target],"selectnumbers,50,10,100,0,lin")." %"|""| FUNC_Status([Kia_connect:range],150,"red",[Kia_connect:range],"orange",[Kia_connect:range],250,"green",[Kia_connect:range])." km"."<div style='border-width:2px;;border-style:solid;;border-color:gray;;position:relative;;width:90px;;height:20px;;background:linear-gradient( to right, red 0px,yellow 30px,green 50px);;'>".STY(" ",FUNC_batt([Kia_connect:batSOC])).STY(::round([Kia_connect:batSOC],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."</div>"\ | |"Accu<dd>Steuerung / Target Soc / Accu Status</dd>" |widget([$SELF:ui_command_3],"uzsuDropDown,---,setChargeTargetSoc,stopCharge,startCharge")|"Target SOC".widget([Kia_connect:status_evStatus_reservChargeInfos_targetSOClist_2_targetSOClevel_target],"selectnumbers,50,10,100,0,lin")." %"|""| FUNC_Status([Kia_connect:range],150,"red",[Kia_connect:range],"orange",[Kia_connect:range],250,"green",[Kia_connect:range])." km"."<div style='border-width:2px;;border-style:solid;;border-color:gray;;position:relative;;width:90px;;height:20px;;background:linear-gradient( to right, red 0px,yellow 30px,green 50px);;'>".STY(" ",FUNC_batt([Kia_connect:batSOC])).STY(::round([Kia_connect:batSOC],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."</div>"\ | ||
\ | \ | ||
|"Komfort<dd>Timer / Klima / Reifen / Türen / Accu Status 12V</dd>" |widget([$SELF:ui_timer_mode],"uzsuDropDown,Aus,heizen,kuehlen").widget([$SELF:ui_timer_Start],"time")|\ | |"Komfort<dd>Timer / Klima / Reifen / Türen / Accu Status 12V</dd>" |widget([$SELF:ui_timer_mode],"uzsuDropDown,Aus,heizen,kuehlen").widget([$SELF:ui_timer_Start],"time")|\ | ||
((::ReadingsVal("Abfall_Abfuhr","Kiaheizen_days",0) != 0)?"Klimatisierung<br>".[Abfall_Abfuhr:Kiaheizen_connect_date]." ".[Abfall_Abfuhr:Kiaheizen_connect_time]:(([$SELF:ui_timer_mode] ne "Aus")?"Klimatisierung<br>".[$SELF:timer_04_c04]:""))|FUNC_tire("Kia_connect")."<br>".FUNC_door("Kia_connect")|\ | ((::ReadingsVal("Abfall_Abfuhr","Kiaheizen_days",0) != 0)?"Klimatisierung<br>".[Abfall_Abfuhr:Kiaheizen_connect_date]." ".[Abfall_Abfuhr:Kiaheizen_connect_time]:(([$SELF:ui_timer_mode] ne "Aus")?"Klimatisierung<br>".[$SELF:timer_04_c04]:""))|FUNC_tire("Kia_connect")."<br>".FUNC_door("Kia_connect")|\ | ||
"12 V<div style='border-width:2px;;border-style:solid;;border-color:gray;;position:relative;;width:90px;;height:20px;;background:linear-gradient( to right, red 0px,yellow 30px,green 50px);;'>".STY(" ",FUNC_batt([Kia_connect:bat12v])).STY(::round([Kia_connect:bat12v],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."</div>"\ | "12 V<div style='border-width:2px;;border-style:solid;;border-color:gray;;position:relative;;width:90px;;height:20px;;background:linear-gradient( to right, red 0px,yellow 30px,green 50px);;'>".STY(" ",FUNC_batt([Kia_connect:bat12v])).STY(::round([Kia_connect:bat12v],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."</div>"\ | ||
\ | \ | ||
|"<dd> Auswahl / Temperatur / Klima Status / Temperatur innen</dd>"| widget([$SELF:ui_command_2],"uzsuDropDown,---,stopClimate,startHeating,startCooling")|\ | |"<dd> Auswahl / Temperatur / Klima Status / Temperatur innen</dd>"| 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<br>Cool".widget([Kia_connect:status_airTemp_value_target_Sommer],"selectnumbers,16,1,25,0,lin")."°C"|(([Kia_connect:status_airCtrlOn] eq "true")?'<span style="color:red">Klima läuft</span>':'<span style="color:green">Klima aus</span>')."<br>".(([Kia_connect:status_defrost] eq "true")?'Defrost ein':'Defrost aus') |"Aktuell<br>".[Kia_connect:status_airTemp_value]."°C"\ | "Heat".widget([Kia_connect:status_airTemp_value_target_Winter],"selectnumbers,20,1,27,0,lin")."°C<br>Cool".widget([Kia_connect:status_airTemp_value_target_Sommer],"selectnumbers,16,1,25,0,lin")."°C"|(([Kia_connect:status_airCtrlOn] eq "true")?'<span style="color:red">Klima läuft</span>':'<span style="color:green">Klima aus</span>')."<br>".(([Kia_connect:status_defrost] eq "true")?'Defrost ein':'Defrost aus') |"Aktuell<br>".[Kia_connect:status_airTemp_value]."°C"\ | ||
\ | \ | ||
|"WallBox (WB_1_lp1)<dd>Lademodus / Info Status / Ladezeit / Leistung</dd>"|widget([$SELF:ui_command_4],"uzsuDropDown,---,SofortLaden,Min+PV,NurPV,Stop,Standby,Hausspeicher_Sperren")|[WB_1:lp_1_PlugStat]." ".[WB_1:lp_1_ChargeStat]| | |"WallBox (WB_1_lp1)<dd>Lademodus / Info Status / Ladezeit / Leistung</dd>"|[WB_1:ChargeMode]."<br>".widget([$SELF:ui_command_4],"uzsuDropDown,---,SofortLaden,Min+PV,NurPV,Stop,Standby,Vorrang_EV,Vorrang_Bat,Hausspeicher_Sperren")|[WB_1:lp_1_PlugStat]." ".[WB_1:lp_1_ChargeStat]|[WB_1:lp_1_TimeRemaining]|[WB_1:lp_1_countPhasesInUse]."P ".[WB_1:lp_1_AConfigured]."A<br>".[WB_1:lp_1_W]." W" | ||
setstate Kia_eNiro_PV 2022-01-12 13:24:24 ui_command_1 --- | |||
setstate Kia_eNiro_PV 2022-01-10 09:18:53 ui_command_2 --- | |||
setstate Kia_eNiro_PV 2021-11-09 07:56:54 ui_command_3 --- | |||
setstate Kia_eNiro_PV 2022-01-12 13:02:41 ui_command_4 --- | |||
setstate Kia_eNiro_PV 2022-01-12 13:02:41 ui_command_before_4 --- | |||
setstate Kia_eNiro_PV 2021-11-29 09:56:58 ui_timer_Start 10:30 | |||
setstate Kia_eNiro_PV 2021-12-02 07:00:00 ui_timer_mode Aus | |||
</syntaxhighlight> | |||
=====Kostal Plenticore mit Speicher===== | |||
Zu diesem Thema gibt es noch die Wiki Seite [[Kostal Plenticore Plus]], die alles rund um den Wechselrichter und vieles mehr erklärt. | |||
Die hier beschriebene openWB und Kia connect Anbindung bedient sich der Hausspeichersteuerung, um diesen beim Laden der BEV zu sperren. | |||
Im DOIF kann an den entsprechenden Stellen natürlich auch ein anders Kommando zum Sperren verwendet werden. | |||
== Weiterführende Links == | |||
* [https://openwb.de openWB Website] | |||
* [https://github.com/snaptec/openWB/wiki openWB Wiki bei GitHub] | |||
* [https://www.openwb.de/forum/viewtopic.php?f=6&t=4159 openWB Forum (Diskussion zu diesem Artikel)] | |||
* [https://openwb.de/forum/viewtopic.php?t=577 openWB Forum (Liste der MQTT-Topics)] | |||
[[Kategorie:Elektromobilität]] | |||
[[Kategorie:HOWTOS]] | |||
[[Kategorie:Wallboxen]] | |||
Aktuelle Version vom 22. Januar 2024, 12:17 Uhr
Integration der openWB in FHEM - Ladeleistung anzeigen und Umschalten des Lademodus
Ausgangssituation ist ein funktionierendes FHEM, ohne weitere Vorbedingungen.
defmod openwb MQTT <openWBip>:1883
attr openwb room Auto,MQTT
Dadurch wird der MQTT-Server der openWB angesprochen, FHEM ist der Client. Ein Ladepunkt wird als MQTT_Device angelegt:
defmod lp1 MQTT_DEVICE
attr lp1 IODev openwb
attr lp1 publishSet_chargeMode openWB/set/ChargeMode
attr lp1 room Auto,Dashboard,MQTT
attr lp1 stateFormat power
attr lp1 subscribeReading_chargeMode openWB/global/ChargeMode
attr lp1 subscribeReading_plugStat openWB/lp/1/boolPlugStat
attr lp1 subscribeReading_power openWB/lp/1/W
Die Umsetzung basiert auf openWB 1.9.x, der Lademodus "ChargeMode" gilt hier noch global für alle Ladepunkte.
Beispielhaft die Definition des zweiten Ladepunktes, eine zweite openWB, die als "nur Ladepunkt" mit der angesprochenen openWB verbunden ist.
Eine openWB kann derzeit 8 Ladepunkte verwalten, die Nummern müssen entsprechend inkrementiert werden.
defmod lp2 MQTT_DEVICE
attr lp2 IODev openwb
attr lp2 publishSet_chargeMode openWB/set/ChargeMode
attr lp2 room Auto,Dashboard,MQTT
attr lp2 stateFormat power
attr lp2 subscribeReading_chargeMode openWB/global/ChargeMode
attr lp2 subscribeReading_plugStat openWB/lp/2/boolPlugStat
attr lp2 subscribeReading_power openWB/lp/2/W
Die MQTT-Topics zum Lesen und Schreiben von Werten sind ganz unten auf dieser Wiki-Seite zu finden.
Die Einbindung in die TabletUI sieht bei mir so aus:
<div class="cell-60 left-space right-space">
<div data-type="symbol" data-icon="fa-car" class="tall compressed" data-color="lightgray">
<div data-type="circlemenu" data-direction="full" class="mini" style="top: -0.5em;">
<ul class="mini">
<li><div data-type="push" data-device="lp1" data-get="chargeMode" data-states='[0,1,2,3,4]' data-colors='["lightgreen","greenyellow","yellow","grey","black"]' data-icons='["fa-bolt","fa-plus-circle","fa-sun-o","fa-pause-circle-o","fa-stop-circle-o"]' data-background-icon=""></div></li>
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="0" data-get-on="0" data-icon="fa-bolt" data-color="lightgreen" data-background-icon=""></div></li>
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="1" data-get-on="1" data-icon="fa-plus-circle" data-color="greenyellow" data-background-icon=""></div></li>
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="2" data-get-on="2" data-icon="fa-sun-o" data-color="yellow" data-background-icon=""></div></li>
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="3" data-get-on="3" data-icon="fa-pause-circle-o" data-color="grey" data-background-icon=""></div></li>
<li><div data-type="push" data-device="lp1" data-set="chargeMode" data-get="chargeMode" data-set-on="4" data-get-on="4" data-icon="fa-stop-circle-o" data-color="black" data-background-icon=""></div></li>
</ul>
</div>
<div style="font-size: 30% !important;" class="mini " data-pre-text="" data-type="label" data-device="lp1" data-get="power" data-unit="" data-factor="1" data-fix="0"></div>
<div data-type="symbol" data-device="lp1" data-get="plugStat" data-states='[0,1]' data-colors='["white","black"]' data-icons='["","fa-plug"]' data-background-icon="" class="mini" style="font-size: 30% !important; top:1em;"></div></li>
</div>
</div>
Integration OpenWB in FHEM - Übertragung von EVU, PV und Batteriewerten an openWB
Ausgangssituation ist ein funktionierendes FHEM-System, bei dem bereits der digitale Stromzähler ("Moderne Meßeinrichtung") über das Modul 47_OBIS und der PV-Wechselrichter über ein entsprechendes Modul, z.B. ModbusAttr integriert sind. Als OpenWB-System wurde hier eine reale OpenWB-Wallbox angebunden.
Datenquellen
Die OpenWB erwartet 1-3 Typen von Datenquellen in dieser Konstellation:
- Die EVU-Schnittstelle, mit der als wesentlicher Steuerparameter der Ladeleistung die Leistungsmessung am Hausübergang herangezogen wird, und daneben die Zählerwerte für Netzbezug und Einspeisung zur Visualisierung übertragen werden sollten. Nur, falls phasenbezogenes Lastmanagement erforderlich sein sollte, sind auch die einzelnen Phasenleistungswerte vom Stromzähler nötig (was nicht jede Moderne Meßeinrichtung auf der OBIS-Schnittstelle bereitstellt)
- Die PV-Schnittstelle, die ebenfalls primär visualisierende Bedeutung hat.
- Die Batteriespeicher-Schnittstelle
OpenWB kann auch z.B. rein mit einer PV-Schnittstelle betrieben werden, in diesem Fall wird ein konstanter Leistungswert für den Hausbezug angenommen.
Kommunikationsprotokoll
Zur Kommunikation mit FHEM bieten sich 2 Methoden an:
- HTTP-Abfrage durch OpenWB bei FHEM durch das generische HTTP-Modul von OpenWB Diese Methode beschreibe ich nicht, weil sie mehr Overhead erzeugt und seitens FHEM die Einrichtung eines CSRF-Token-freien Web-Kanals erfordert
- MQTT-Push durch FHEM zur OpenWB Diese Methode erscheint mir vorteilhafter, weil auf einer stehenden TCP-Verbindung lediglich Meßwerte gepusht werden.
Implementierung
Vorbereitung
In der OpenWB-Web-UI unter Modulkonfiguration die entsprechenden Module (EVU, PV, Batterie) auf MQTT stellen. Hinweis: Nicht alle dabei erscheinenden MQTT-Topics müssen mit Werten beliefert werden! Sowohl bei der EVU-Schnittstelle wie bei PV reichen Momentanleistung und Zählerstände für eine zufriedenstellende Anbindung!
Definition der OpenWB als MQTT-Target
defmod openwb_mqtt MQTT2_CLIENT <ip-der-openwb>:1883 attr openwb_mqtt autocreate simple attr openwb_mqtt subscriptions openWB/lp/1/#
Übertragung der EVU-Meßwerte
In diesem Beispiel heißt das die Stromzählerdaten liefernde Device am OBIS-Modul "MT175". Die Zahlen werden per Notify von diesem Device auf MQTT kopiert:
defmod openwb_evu_cons notify MT175:total_consumption:.* { fhem("set openwb_mqtt publish openWB/set/evu/WhImported " . $EVTPART1); } defmod openwb_evu_feed notify MT175:total_feed:.* { fhem("set openwb_mqtt publish openWB/set/evu/WhExported " . $EVTPART1); } defmod openwb_evu_w notify MT175:power:.* { fhem("set openwb_mqtt publish openWB/set/evu/W " . int($EVTPART1)); }
Übertragung der PV-Meßwerte
Sofern die Daten für Momentanleistung und Zählerstand direkt in einem Device vorliegen, können analoge Notifys für dieses Device implementiert werden. Die Zielwerte lauten:
- Für den Momentan-Leistungswert
openWB/set/pv/1/W
- Für den Zählerstand
openWB/set/pv/1/WhCounter
Dabei muss beachtet werden, dass - wie bei der EVU-Schnittstelle - nur Integerwerte für die Momentanleistung übertragen werden dürfen.
Anbindung an Alexa
Der generische Smarthome-Skill "FHEMConnector" erlaubt nur die leider immer noch sehr limitierte Syntax von Amazon Alexa. Im Folgenden werden die Definitionen für die Befehle:
- "Alexa, schalte Überschussladen ein"
- "Alexa, schalte Überschussladen aus"
- "Alexa, schalte Überschussladen auf 6 (Prozent)"
dargestellt. "Überschussladen auf 6" bedeutet dabei real den "Min+PV", also Überschussladen mit Minimalleistung von 6 Ampere. Je nach Tagesform von Amazon ist dabei das Sprechen von "Prozent" nötig, auch wenn dies natürlich sachlich falsch ist.
define openwb_ueberschuss dummy attr openwb_ueberschuss alexaName Überschussladen attr openwb_ueberschuss genericDeviceType light attr openwb_ueberschuss readingList pct attr openwb_ueberschuss setList on off pct define openwb_ueberschuss_on notify openwb_ueberschuss:on set openwb_mqtt publish openWB/set/ChargeMode 2 define openwb_ueberschuss_off notify openwb_ueberschuss:off set openwb_mqtt publish openWB/set/ChargeMode 3 define openwb_ueberschuss_pct notify openwb_ueberschuss:pct:.* set openwb_mqtt publish openWB/config/set/pv/minCurrentMinPv $EVTPART1 ;; set openwb_mqtt publish openWB/set/ChargeMode 1
Anwendungs Beispiele
Komplexe Anbindung
Hier mal ein Beispiel mit weiteren Schnittstellen in der Haussteuerung. Im Hintergrund arbeitet ein Wechselrichter Schwarm mit einem Hausspeicher, der beim BEV Laden gesperrt wird. Die openWB kommuniziert direkt mit den zwei Kostal Wechselrichtern, dem KSEM und dem am Master angeschlossenen Speicher. Das BEV ist über Kia Connect angebunden.
Verwendete Schnittstellen / Devices
openWB MQTT
Wie oben beschrieben mit folgender MQTT definition. Im Bild ist das DOIF dargestellt und das MQTT Device als kurze Darstellung unterhalb der Tabelle. Das MQTT wird nur zur Kopplung verwendet, hat jedoch jetzt auch ein stateFormat inklusieve Statistiken erhalten.
RAW des MQTT Device
defmod WB_1 MQTT2_DEVICE WB_1_MQTT2
attr WB_1 DbLogExclude .*
attr WB_1 DbLogInclude lp_1_.*,.*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_1_.*,.*AllChargePoints.*,ChargeMode
attr WB_1 group PV Eigenverbrauch
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/faultState:.* lp_2_faultState\
$DEVICETOPIC/set/lp/2/faultStr:.* lp_2_faultStr\
$DEVICETOPIC/set/lp/2/ChargePointEnabled:.* lp_2_ChargePointEnabled
attr WB_1 room MQTT2_DEVICE,Strom->Photovoltaik
attr WB_1 setList Lademodus:SofortLaden,Min+PV,NurPV,Stop,Standby { my %h=(SofortLaden=>'0','Min+PV'=>'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) }
attr WB_1 sortby 311
attr WB_1 stateFormat {\
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")? "<span style='color:red'>SofortLaden</span>" : ($ChargeMode eq "MinPV")? "<span style='color:orange'>Min+PV</span>" : ($ChargeMode eq "NurPV")? "<span style='color:green'>NurPV</span>" : $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")."<br>".ReadingsVal($name,"lp_1_ChargeStat","n/a");;\
my $lp_1_Status_2 = ReadingsVal($name,"lp_1_TimeRemaining","n/a");;\
\
my $lp_1_Power_d = ReadingsVal($name,"lp_1_kWhDailyCharged",0)." kWh";;\
my $lp_1_Power_m = round(ReadingsVal($name,"lp_1_kWhCounter_Month",0),0)." kWh";;\
my $lp_1_Power_j = sprintf("%04d / %04d",ReadingsVal($name,"lp_1_kWhCounter_Year",0),ReadingsVal($YearBefore,"lp_1_kWhCounter_Year",0));;\
my $lp_1_Power_t = round(ReadingsVal($name,"lp_1_kWhCounter",0),0)." kWh";;\
\
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")."<br>".ReadingsVal($name,"lp_2_ChargeStat","n/a");;\
my $lp_2_Status_2 = "<br>".ReadingsVal($name,"lp_2_TimeRemaining","n/a");;\
\
my $lp_2_Power_d = ReadingsVal($name,"lp_2_kWhDailyCharged",0)." kWh";;\
my $lp_2_Power_m = round(ReadingsVal($name,"lp_2_kWhCounter_Month",0),0)." kWh";;\
my $lp_2_Power_j = sprintf("%04d / %04d",ReadingsVal($name,"lp_2_kWhCounter_Year",0),ReadingsVal($YearBefore,"lp_2_kWhCounter_Year",0));;\
my $lp_2_Power_t = round(ReadingsVal($name,"lp_2_kWhCounter",0),0)." kWh";;\
\
"<html><table border=2 bordercolor='darkgreen' cellspacing=0 style='width: 100%'>\
<colgroup>\
<col span='1' style='width: 52%;;'>\
<col span='1' style='width: 12%;;'>\
<col span='1' style='width: 12%;;'>\
<col span='1' style='width: 12%;;'>\
<col span='1' style='width: 12%;;'>\
</colgroup>\
<tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'>Wallbox</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>$ChargeMode</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Status</td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'>Restladezeit</td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'>Leistung</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'> ; ;".$lp_1_Name."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Status_1."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Status_2."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power_1."<br>".$lp_1_Power."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'> ; ;".$lp_2_Name."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Status_1."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Status_2."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power_1."<br>".$lp_2_Power."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'>Statistik vom $date</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>aktuell</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Heute</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Monat</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Jahr/Vorjahr</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'> ; ;".$lp_1_Name."<td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power_d."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power_m."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_1_Power_j."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'> ; ;".$lp_2_Name."<td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power_d."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power_m."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$lp_2_Power_j."</td></tr>\
</table>\
</html>"\
}
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) }
Kia connect MQTT
Das Kia_connect Device empfängt und sendet die MQTT Nachrichten zum Node-red Flow für das Kia BEV.
RAW des Kia connect
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 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/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
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);;;;}
Node-red
Node-red habe ich einfach in einem Docker Container runter geladen und gestartet. Über Port 1880 kommt man direkt in die GUI und kann den ersten Flow laden.
docker-compose .yml Eintrag
node-red:
image: nodered/node-red:latest
restart: always
environment:
- TZ=Europe/Berlin
ports:
- 1880:1880
volumes:
- ./node-red/data:/data
Danach fehlt im Container noch folgende Erweiterung für den Node-red Flow
npm install node-red-contrib-bluelinky
Kia Connect
Kia connect ist eine API für Kia und Hyundai E-Autos mit der man Daten vom Auto abfragen kann und auch einige Steuerungen möglich sind. Mit Node-red und BlueLinky wird die Schnittstelle bedient. Der Flow ist nicht ursprünglich von mir, wurde jedoch noch erweitert. Vor dem Laden des Flows sind noch die persönlichen Verbindungsdaten im JSON einzutragen. Nach dem Laden ist ein Test mit den Inject Symbolen und der Debug Funktionalität möglich und auch sinnvoll. Unterhalb der MQTT - und BlueLinky Symbole sollte "Verbunden" oder "Ready" erscheinen.
Wichtig beim Kia ist, dass für das Laden über die openWB als SOC Ziel 80% im standard Modus konfiguriert wird. Ansonsten wundert man sich warum das Laden einfach nicht starten möchte. Im Default ist dort bei mir nur 50% eingetragen gewesen :-). Mit jetzt 100% kann die openWB auch selber einen Ziel SOC bestimmen, ansonsten hört das BEV einfach selber auf zu laden.
Weiterhin sollte man darauf achten, dass man nur eine begrenzte Anzahl von Nachrichten mit dem Kia BEV pro Tag austauschen kann. Das wurde im DOIF schon etwas berücksichtigt (1x pro Stunde), kann jedoch bei gleichzeitiger Verwendung der Handy App oder der SOC Abfrage im openWB Kia Modul auch mal zu Fehlern führen. Durch die Stündliche Status Abfrage im DOIF kommt es natürlich zu Verzögerungen im FHEM Status. Dann einfach einmal Manuell abfragen.
Node-red JSON Import
[ {
"id": "866c75dd.edd9a8",
"type": "tab",
"label": "Kia e-Niro",
"disabled": false,
"info": ""
},
{
"id": "bb13a99d.68b8f8",
"type": "mqtt-broker",
"name": "mqtt_Server",
"broker": "<FHEM MQTT IP Adresse>",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"compatmode": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"sessionExpiry": ""
},
{
"id": "452a3304.58c8fc",
"type": "bluelinky",
"username": "<Mail Adresse bei Kia>",
"password": "<Passwort>",
"region": "EU",
"pin": "<Pin>",
"vin": "<VIN>",
"brand": "kia"
},
{
"id": "91a345fa.5757a8",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/get_status",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"inputs": 0,
"x": 260,
"y": 280,
"wires": [
[
"15dfb508.c6497b",
"ce62ba4f.d86548",
"3f82a275.5a0b6e",
"24d5e0b.3aafc2"
]
]
},
{
"id": "5ad085b9.05739c",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/start_climate",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"nl": false,
"rap": false,
"inputs": 0,
"x": 270,
"y": 680,
"wires": [
[
"b27d74de.38c808",
"33b1bc85.662694",
"ce62ba4f.d86548",
"24d5e0b.3aafc2"
]
]
},
{
"id": "15dfb508.c6497b",
"type": "car-status",
"z": "866c75dd.edd9a8",
"name": "Get status",
"dorefresh": true,
"parsed": false,
"bluelinky": "452a3304.58c8fc",
"x": 1110,
"y": 280,
"wires": [
[
"cccc9476.d56dd8",
"226ed925.607bb6"
]
]
},
{
"id": "87abdd88.8ff4d",
"type": "car-odometer",
"z": "866c75dd.edd9a8",
"name": "Get car odometer",
"bluelinky": "452a3304.58c8fc",
"x": 1130,
"y": 200,
"wires": [
[
"40d2361c.579588",
"226ed925.607bb6"
]
]
},
{
"id": "31100f9a.40008",
"type": "function",
"z": "866c75dd.edd9a8",
"name": "locationWrapper",
"func": "if(msg.payload.hasOwnProperty(\"body\")) {\n msg.payload = {\"error\":true};\n return msg;\n}\nelse {\n\n msg.payload = { \n \"location\": msg.payload,\n \"error\": false\n };\n \n return msg;\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1490,
"y": 120,
"wires": [
[
"85a07155.a0f9f",
"262df5dc.57916a",
"f487d6d6.a4d568"
]
]
},
{
"id": "bea1d927.0f3908",
"type": "car-location",
"z": "866c75dd.edd9a8",
"name": "Get car location",
"bluelinky": "452a3304.58c8fc",
"x": 1120,
"y": 120,
"wires": [
[
"31100f9a.40008",
"226ed925.607bb6"
]
]
},
{
"id": "3c949d67.0d83b2",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/get_location",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"nl": false,
"rap": false,
"inputs": 0,
"x": 270,
"y": 120,
"wires": [
[
"bea1d927.0f3908",
"ce62ba4f.d86548",
"3f82a275.5a0b6e",
"24d5e0b.3aafc2"
]
]
},
{
"id": "cccc9476.d56dd8",
"type": "function",
"z": "866c75dd.edd9a8",
"name": "analyseStatus",
"func": "if(msg.payload.hasOwnProperty(\"body\")) {\n msg.payload = {\"error\":true};\n return msg;\n}\nelse {\n let status = msg.payload;\n status.airTemp.value = 14+(parseInt(status.airTemp.value,16)/2);\n try{\n status.evStatus.reservChargeInfos.reservChargeInfo.reservChargeInfoDetail.reservFatcSet.airTemp.value = 14+(parseInt(status.evStatus.reservChargeInfos.reservChargeInfo.reservChargeInfoDetail.reservFatcSet.airTemp.value,16)/2);\n status.evStatus.reservChargeInfos.reserveChargeInfo2.reservChargeInfoDetail.reservFatcSet.airTemp.value = 14+(parseInt(status.evStatus.reservChargeInfos.reserveChargeInfo2.reservChargeInfoDetail.reservFatcSet.airTemp.value,16)/2);\n } catch(e) {}\n\n let time = status.evStatus.remainTime2.atc.value/60;\n let result = { \n \"batSOC\": status.evStatus.batteryStatus,\n \"connected\": (status.evStatus.batteryPlugin !== 0),\n \"charging\": status.evStatus.batteryCharge,\n \"targetSOC\": status.evStatus.reservChargeInfos.targetSOClist[1].targetSOClevel,\n \"time2targetSOC\": (Math.floor(time) + \":\" + (\"0\" + Math.floor((time % 1)*60)).slice(-2)), // h:mm\n \"range\": status.evStatus.drvDistance[0].rangeByFuel.totalAvailableRange.value,\n \"bat12v\": status.battery.batSoc\n };\n \n //msg.payload = result;\n msg.payload = {\n \"status\": status,\n \"error\": false\n \n };\n return msg;\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1480,
"y": 280,
"wires": [
[
"3efceea0.c81b12",
"262df5dc.57916a",
"f487d6d6.a4d568"
]
]
},
{
"id": "85a07155.a0f9f",
"type": "mqtt out",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "bluelinky/location",
"qos": "",
"retain": "",
"broker": "bb13a99d.68b8f8",
"x": 1910,
"y": 120,
"wires": []
},
{
"id": "3efceea0.c81b12",
"type": "mqtt out",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "bluelinky/status",
"qos": "",
"retain": "",
"broker": "bb13a99d.68b8f8",
"x": 1900,
"y": 280,
"wires": []
},
{
"id": "327104fc.71e1bc",
"type": "mqtt out",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "bluelinky/odometer",
"qos": "",
"retain": "",
"broker": "bb13a99d.68b8f8",
"x": 1910,
"y": 200,
"wires": []
},
{
"id": "844a32f4.2e029",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/stop_climate",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"inputs": 0,
"x": 270,
"y": 760,
"wires": [
[
"7d3ae860.d8c9a8",
"33b1bc85.662694",
"ce62ba4f.d86548",
"24d5e0b.3aafc2"
]
]
},
{
"id": "57d91e50.7e96",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/start_charging",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"inputs": 0,
"x": 280,
"y": 820,
"wires": [
[
"6eebc52c.ee23dc",
"33b1bc85.662694",
"ce62ba4f.d86548",
"24d5e0b.3aafc2"
]
]
},
{
"id": "6029f0a0.b73e",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/stop_charging",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"nl": false,
"rap": false,
"inputs": 0,
"x": 280,
"y": 880,
"wires": [
[
"84a1ae.74912e5",
"33b1bc85.662694",
"ce62ba4f.d86548",
"24d5e0b.3aafc2"
]
]
},
{
"id": "c5ecf76c.e753c8",
"type": "start-car",
"z": "866c75dd.edd9a8",
"name": "Start car",
"bluelinky": "452a3304.58c8fc",
"x": 1100,
"y": 680,
"wires": [
[
"811aa567.e89f98",
"f487d6d6.a4d568"
]
]
},
{
"id": "6eebc52c.ee23dc",
"type": "start-charge",
"z": "866c75dd.edd9a8",
"name": "Start Charging",
"bluelinky": "452a3304.58c8fc",
"x": 1120,
"y": 820,
"wires": [
[
"811aa567.e89f98",
"f487d6d6.a4d568"
]
]
},
{
"id": "84a1ae.74912e5",
"type": "stop-charge",
"z": "866c75dd.edd9a8",
"name": "Stop Charging",
"bluelinky": "452a3304.58c8fc",
"x": 1120,
"y": 880,
"wires": [
[
"811aa567.e89f98",
"f487d6d6.a4d568"
]
]
},
{
"id": "7d3ae860.d8c9a8",
"type": "stop-car",
"z": "866c75dd.edd9a8",
"name": "Stop car",
"bluelinky": "452a3304.58c8fc",
"x": 1100,
"y": 760,
"wires": [
[
"811aa567.e89f98",
"f487d6d6.a4d568"
]
]
},
{
"id": "b27d74de.38c808",
"type": "json",
"z": "866c75dd.edd9a8",
"name": "",
"property": "payload",
"action": "obj",
"pretty": false,
"x": 750,
"y": 680,
"wires": [
[
"c5ecf76c.e753c8",
"33b1bc85.662694"
]
]
},
{
"id": "45a6a8e6.2abfd8",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/get_odometer",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"inputs": 0,
"x": 280,
"y": 200,
"wires": [
[
"87abdd88.8ff4d",
"ce62ba4f.d86548",
"3f82a275.5a0b6e",
"24d5e0b.3aafc2"
]
]
},
{
"id": "33b1bc85.662694",
"type": "debug",
"z": "866c75dd.edd9a8",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 930,
"y": 920,
"wires": []
},
{
"id": "ce62ba4f.d86548",
"type": "mqtt out",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "bluelinky/req_received",
"qos": "",
"retain": "",
"broker": "bb13a99d.68b8f8",
"x": 860,
"y": 480,
"wires": []
},
{
"id": "1babee6c.1c2982",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/get_all",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"inputs": 0,
"x": 250,
"y": 360,
"wires": [
[
"ce62ba4f.d86548",
"3f82a275.5a0b6e",
"24d5e0b.3aafc2",
"4375fbb9.00fb44"
]
]
},
{
"id": "262df5dc.57916a",
"type": "debug",
"z": "866c75dd.edd9a8",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1850,
"y": 80,
"wires": []
},
{
"id": "811aa567.e89f98",
"type": "debug",
"z": "866c75dd.edd9a8",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1470,
"y": 1040,
"wires": []
},
{
"id": "3f82a275.5a0b6e",
"type": "debug",
"z": "866c75dd.edd9a8",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 930,
"y": 80,
"wires": []
},
{
"id": "24d5e0b.3aafc2",
"type": "change",
"z": "866c75dd.edd9a8",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "pending",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 790,
"y": 1140,
"wires": [
[
"4dd1ea4a.52f144",
"fecad185.324f8"
]
]
},
{
"id": "f487d6d6.a4d568",
"type": "change",
"z": "866c75dd.edd9a8",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "idle",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1910,
"y": 760,
"wires": [
[
"4dd1ea4a.52f144",
"fecad185.324f8"
]
]
},
{
"id": "4dd1ea4a.52f144",
"type": "mqtt out",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "bluelinky/req_active",
"qos": "",
"retain": "",
"broker": "bb13a99d.68b8f8",
"x": 2140,
"y": 1100,
"wires": []
},
{
"id": "fecad185.324f8",
"type": "debug",
"z": "866c75dd.edd9a8",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 2110,
"y": 1160,
"wires": []
},
{
"id": "40d2361c.579588",
"type": "function",
"z": "866c75dd.edd9a8",
"name": "odometerWrapper",
"func": "if(msg.payload.hasOwnProperty(\"body\")) {\n msg.payload = {\"error\":true};\n return msg;\n}\nelse {\n msg.payload = { \n \"odometer\": msg.payload,\n \"error\": false\n };\n\n return msg;\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1490,
"y": 200,
"wires": [
[
"327104fc.71e1bc",
"262df5dc.57916a",
"f487d6d6.a4d568"
]
]
},
{
"id": "226ed925.607bb6",
"type": "debug",
"z": "866c75dd.edd9a8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1430,
"y": 80,
"wires": []
},
{
"id": "4375fbb9.00fb44",
"type": "car-fullstatus",
"z": "866c75dd.edd9a8",
"name": "Get full status",
"dorefresh": true,
"bluelinky": "452a3304.58c8fc",
"x": 1120,
"y": 360,
"wires": [
[
"226ed925.607bb6",
"69b6c4df.ea6bcc",
"89681a97.9e24d8",
"92dc3ff4.1d6e3"
]
]
},
{
"id": "69b6c4df.ea6bcc",
"type": "function",
"z": "866c75dd.edd9a8",
"name": "locationFromFullstatus",
"func": "if(msg.payload.hasOwnProperty(\"body\")) {\n msg.payload = {\"error\":true};\n return msg;\n}\nelse {\n\n msg.payload = { \n \"location\": msg.payload.vehicleLocation,\n \"error\": false\n };\n \n return msg;\n}\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1500,
"y": 360,
"wires": [
[
"85a07155.a0f9f",
"331e5860.907808"
]
]
},
{
"id": "92dc3ff4.1d6e3",
"type": "function",
"z": "866c75dd.edd9a8",
"name": "statusFromFullstatus",
"func": "if(msg.payload.hasOwnProperty(\"body\")) {\n msg.payload = {\"error\":true};\n return msg;\n}\nelse {\n let status = msg.payload.vehicleStatus;\n try{\n status.airTemp.value = 14+(parseInt(status.airTemp.value,16)/2);\n status.evStatus.reservChargeInfos.reservChargeInfo.reservChargeInfoDetail.reservFatcSet.airTemp.value = 14+(parseInt(status.evStatus.reservChargeInfos.reservChargeInfo.reservChargeInfoDetail.reservFatcSet.airTemp.value,16)/2);\n status.evStatus.reservChargeInfos.reserveChargeInfo2.reservChargeInfoDetail.reservFatcSet.airTemp.value = 14+(parseInt(status.evStatus.reservChargeInfos.reserveChargeInfo2.reservChargeInfoDetail.reservFatcSet.airTemp.value,16)/2);\n } catch(e) {}\n\n msg.payload = { \n \"status\": status,\n \"error\": false\n };\n \n return msg;\n}\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1500,
"y": 480,
"wires": [
[
"3efceea0.c81b12",
"f487d6d6.a4d568",
"331e5860.907808"
]
]
},
{
"id": "89681a97.9e24d8",
"type": "function",
"z": "866c75dd.edd9a8",
"name": "odometerFromFullstatus",
"func": "if(msg.payload.hasOwnProperty(\"body\")) {\n msg.payload = {\"error\":true};\n return msg;\n}\nelse {\n\n msg.payload = { \n \"odometer\": msg.payload.odometer,\n \"error\": false\n };\n \n return msg;\n}\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1510,
"y": 420,
"wires": [
[
"327104fc.71e1bc",
"331e5860.907808"
]
]
},
{
"id": "331e5860.907808",
"type": "debug",
"z": "866c75dd.edd9a8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1850,
"y": 520,
"wires": []
},
{
"id": "aa4d220b.f7e19",
"type": "set-chargetargets",
"z": "866c75dd.edd9a8",
"name": "Set charge targets",
"bluelinky": "452a3304.58c8fc",
"x": 1130,
"y": 960,
"wires": [
[
"811aa567.e89f98",
"f487d6d6.a4d568"
]
]
},
{
"id": "4c03338d.2f15ec",
"type": "login",
"z": "866c75dd.edd9a8",
"name": "Login",
"bluelinky": "452a3304.58c8fc",
"x": 1090,
"y": 1040,
"wires": [
[
"811aa567.e89f98"
]
]
},
{
"id": "28b868f5.16cb48",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "43200",
"crontab": "",
"once": true,
"onceDelay": "12",
"topic": "",
"payloadType": "date",
"x": 950,
"y": 1040,
"wires": [
[
"4c03338d.2f15ec"
]
]
},
{
"id": "db9ecdb5.a9683",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/set_chargetargets",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"nl": false,
"rap": false,
"inputs": 0,
"x": 290,
"y": 960,
"wires": [
[
"7064a8d53256b646",
"ce62ba4f.d86548",
"24d5e0b.3aafc2"
]
]
},
{
"id": "44155ad70c47b0dd",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 940,
"y": 260,
"wires": [
[
"15dfb508.c6497b"
]
]
},
{
"id": "7064a8d53256b646",
"type": "json",
"z": "866c75dd.edd9a8",
"name": "",
"property": "payload",
"action": "obj",
"pretty": false,
"x": 750,
"y": 960,
"wires": [
[
"33b1bc85.662694",
"aa4d220b.f7e19"
]
]
},
{
"id": "7064395e56292844",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 940,
"y": 340,
"wires": [
[
"4375fbb9.00fb44"
]
]
},
{
"id": "5f9ff828080f5fe6",
"type": "lock-car",
"z": "866c75dd.edd9a8",
"name": "Lock car",
"bluelinky": "452a3304.58c8fc",
"x": 1100,
"y": 560,
"wires": [
[
"811aa567.e89f98",
"f487d6d6.a4d568"
]
]
},
{
"id": "492f5b94a865e47b",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 940,
"y": 540,
"wires": [
[
"5f9ff828080f5fe6"
]
]
},
{
"id": "d6f3f148e765caf9",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/car_lock",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"nl": false,
"rap": false,
"inputs": 0,
"x": 260,
"y": 560,
"wires": [
[
"5f9ff828080f5fe6",
"ce62ba4f.d86548"
]
]
},
{
"id": "cdc13a486db22b8e",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/car_unlock",
"qos": "0",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"nl": false,
"rap": false,
"inputs": 0,
"x": 270,
"y": 620,
"wires": [
[
"99f5c3a41ac3e754",
"ce62ba4f.d86548"
]
]
},
{
"id": "99f5c3a41ac3e754",
"type": "unlock-car",
"z": "866c75dd.edd9a8",
"name": "Unlock car",
"bluelinky": "452a3304.58c8fc",
"x": 1110,
"y": 620,
"wires": [
[
"f487d6d6.a4d568",
"811aa567.e89f98"
]
]
},
{
"id": "ab557a0ea621403a",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 940,
"y": 600,
"wires": [
[
"99f5c3a41ac3e754"
]
]
},
{
"id": "a525de86e4374518",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 940,
"y": 740,
"wires": [
[
"7d3ae860.d8c9a8"
]
]
},
{
"id": "0b8cb92c042fe140",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 940,
"y": 800,
"wires": [
[
"6eebc52c.ee23dc"
]
]
},
{
"id": "ae4c2139b08aaa28",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 940,
"y": 860,
"wires": [
[
"84a1ae.74912e5"
]
]
},
{
"id": "dd23108ce63f456d",
"type": "get-monthlyreport",
"z": "866c75dd.edd9a8",
"name": "Get monthly report",
"bluelinky": "452a3304.58c8fc",
"x": 1130,
"y": 1280,
"wires": [
[
"e57eb97531129426"
]
]
},
{
"id": "a6e5e8deb52145f1",
"type": "inject",
"z": "866c75dd.edd9a8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 940,
"y": 1260,
"wires": [
[
"dd23108ce63f456d"
]
]
},
{
"id": "95f1b6f32aafd65b",
"type": "get-tripinfo",
"z": "866c75dd.edd9a8",
"name": "Tripinfo",
"bluelinky": "452a3304.58c8fc",
"x": 1100,
"y": 1220,
"wires": [
[
"e57eb97531129426"
]
]
},
{
"id": "fb2b99958bc48593",
"type": "json",
"z": "866c75dd.edd9a8",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 750,
"y": 1220,
"wires": [
[
"95f1b6f32aafd65b"
]
]
},
{
"id": "5230ebe391325b17",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/get_tripinfo",
"qos": "2",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 270,
"y": 1220,
"wires": [
[
"fb2b99958bc48593"
]
]
},
{
"id": "e57eb97531129426",
"type": "debug",
"z": "866c75dd.edd9a8",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1470,
"y": 1220,
"wires": []
},
{
"id": "4fdf3b1b7811c89f",
"type": "mqtt in",
"z": "866c75dd.edd9a8",
"name": "",
"topic": "req/bluelinky/get_tripinfo",
"qos": "2",
"datatype": "auto",
"broker": "bb13a99d.68b8f8",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 270,
"y": 1280,
"wires": [
[
"dd23108ce63f456d"
]
]
}
]
Kia_eNiro_PV DOIF mit uiTable
Mit diesem DOIF Device werden folgende Funktionalitäten abgebildet: Nun dann noch das DOIF mit dem uiTable für die Status Anzeige und die Steuerung über Pull Down Menüs.
- Status Abfrage
Status jede Stunde zwischen 6 und 23 Uhr (12V min 40%) Status beim Laden alle 15 Minuten (12V min 40%) Anzeige des Kilometerzählers Status des Fahrzeuges zu Hause / unterwegs und beim Laden Fahrzeug Auf/Zu
- Klimatisierung über das Pull Down Menü
unterschiedliche Temperaturen für Heizen und Kühlen Aktuelle Temperatur Heizen/Klima Ein/Aus Timer für zeitgesteuertes Klimatisieren für den Resttag oder den Nächsten Tag (vor der aktuellen Zeit) Klimatisierung über "Abfall" Kalender (es geht nur ein Termin pro Tag, dafür aber komfortabel über das Handy)
- Komfort
Reifen Überwachung Türen / Motorhaube / Kofferraum Überwachung 12V Batterie anzeige, wenn der Ladezustand kleiner 40% ist erfolgt keine weitere Status Abfrage
- ACCU Steuerung
Setzen des Ziel SOC beim Standard Laden Start/Stop Laden Accu Stand und berechnete Restkilometer
- Für openWB integratin im uiTable
Wählen des Lademodus Vorrang EV oder Bat Sperren des Hausspeichers entweder manuell oder automatisch beim Laden. Der vorherige Zustand wird gespeichert Die Freigabe erfolgt über die Wechselrichter Implementierung, siehe dort "Externe Speicher Steuerung" Geschätzte Ladezeit Status Ladepunkt (Plug und Laden) Lade Status Phasen und Leistung
Achtung, die Kia connect Abfragen sind auf ca. 200 pro Tag von Kia limitiert! Durch die Stündliche Status Abfrage im DOIF kommt es natürlich zu Verzögerungen im FHEM Status. Dann einfach einmal manuell abfragen.
Die Kommunikation zum Kia BEV ist manchmal sehr träge, z.B. kann eine Status Abfrage auch mal 3 Minuten dauern, deshalb wurde eine Verriegelung implementiert. Es wird ein Status pending/idle angezeigt. Nur wenn der Zustand "idel" ist, können weitere Abfragen gestartet werden. Läuft z.B. die Status Abfrage kann man ein weiteres Kommando anstarten, es wird jedoch erst abgesetzt, wenn das vorherige Kommando fertig ist. Solange bleibt im Pull Down Menü das neue Kommando stehen.
RAW des DOIF
defmod Kia_eNiro_PV 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] and ## alle 15 Minuten\
[Kia_connect:atHomeStanding] eq "true" and ## wenn das Auto zuhause ist\
[Kia_connect:charging] eq "true" or ## und es geladen wird\
[:58] and [05:00-23:00] ## ansonsten nur jede Stunde\
) and [Kia_connect:bat12v] > 40 ## aber die 12V Batterie sollte noch genügend Ladung haben\
or [$SELF:cmd_event] eq "set_cmd_1" ## Das reagiert auf den Aufruf mit "set <Device> 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"\
)\
) {\
set_Reading("ui_command_before_2",[$SELF:ui_command_2]);;\
\
if ([$SELF:ui_command_2] eq "startHeating") {\
my $airTemp_value= [Kia_connect:status_airTemp_value_target_Winter];;\
fhem_set('Kia_connect startClimate {"defrost": true, "windscreenHeating": true, "temperature": '.$airTemp_value.' , "unit": "C"}');;\
if (AttrVal("$SELF","verbose",0) >= 0)\
{Log 3, "$SELF 2_Klima : startHeating"};;\
}\
if ([$SELF:ui_command_2] eq "startCooling") {\
my $airTemp_value = [Kia_connect:status_airTemp_value_target_Summer];;\
fhem_set('Kia_connect startClimate {"defrost": false, "windscreenHeating": false, "temperature": '.$airTemp_value.' , "unit": "C"}');;\
if (AttrVal("$SELF","verbose",0) >= 0)\
{Log 3, "$SELF 2_Klima : startCooling"};;\
}\
if ([$SELF:ui_command_2] eq "stopClimate") {\
fhem_set("Kia_connect ".[$SELF:ui_command_2]);;\
if (AttrVal("$SELF","verbose",0) >= 0)\
{Log 3, "$SELF 2_Klima : stopClimate"};;\
}\
fhem_set("Abfall update");;\
\
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_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 4_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 4_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_2] eq "car_lock" ## Hier wird das uiTable select ausgewertet\
or [$SELF:ui_command_2] eq "car_unlock"\
)\
) {\
set_Reading("ui_command_before_2",[$SELF:ui_command_2]);;\
\
fhem_set("Kia_connect ".[$SELF:ui_command_2]);;\
if (AttrVal("$SELF","verbose",0) >= 0)\
{Log 3, "$SELF 6_Auf_Zu : ".[$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\
}\
}\
\
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 "Min+PV"\
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"\
)\
) {\
set_Reading("ui_command_before_4",[$SELF:ui_command_4]);;\
\
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 7_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 7_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\
}\
}\
\
8_Speicher_sperren\
{if( !([$SELF:state] eq "off") ## DOIF enabled\
and\
( [$SELF:ui_command_4] eq "Hausspeicher_Sperren" ## Hier wird das uiTable select ausgewertet\
or [WB_1:lp_1_ChargeStat] eq "loading" and\
[WB_1:lp_1_PlugStat] eq "Plugged in"\
)\
) {\
set_Reading("ui_command_before_4",[$SELF:ui_command_4]);;\
\
if([$SELF:WR_1_Speicher_1_ExternControl_smart_laden_before] eq "---") {\
\
if([$SELF:SpeicherExternTrigger] eq "gesperrt" and\
[WR_1_API:Battery_InternControl_MinHomeConsumption] eq "30000" ) {\
set_Reading("WR_1_Speicher_1_ExternControl_smart_laden_before","aktiv");;\
if (AttrVal("$SELF","verbose",0) >= 0)\
{Log 3, "$SELF 8_Speicher_sperren : smart_laden_before aktiv"};;\
} else {\
set_Reading("WR_1_Speicher_1_ExternControl_smart_laden_before","inaktiv");;\
if (AttrVal("$SELF","verbose",0) >= 0)\
{Log 3, "$SELF 8_Speicher_sperren : smart_laden_before inaktiv"};;\
}\
\
fhem_set("WR_1_Speicher_1_ExternControl cmd_2");;\
if (AttrVal("$SELF","verbose",0) >= 0)\
{Log 3, "$SELF 8_Speicher_sperren : smart_Laden startet"};;\
}\
\
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]);;\
}\
}\
}\
}
attr Kia_eNiro_PV DbLogExclude .*
attr Kia_eNiro_PV disable 0
attr Kia_eNiro_PV group PV Eigenverbrauch-Steuerung
attr Kia_eNiro_PV icon car
attr Kia_eNiro_PV room Strom->Photovoltaik
attr Kia_eNiro_PV sortby 401
attr Kia_eNiro_PV 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)? '<span style="color:'.$colorMin.'">'.$statusMin.'</span>' : ($value > $max)? '<span style="color:'.$colorMax.'">'.$statusMax.'</span>' : '<span style="color:'.$colorMiddel.'">'.$statusMiddle.'</span>';;\
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 = '<span style="color:green">Reifendruck okay</span>';;\
\
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 = '<span style="color:red">Reifen Störung<br>';;\
if ($VL == 1){$ret.=' /VL'};;\
if ($VR == 1){$ret.=' /VR'};;\
if ($HL == 1){$ret.=' /HL'};;\
if ($HR == 1){$ret.=' /HR'};;\
$ret = $ret.'</span>';;\
}\
return $ret;;\
}\
sub FUNC_door {\
my($car)=@_;;\
my $ret = '<span style="color:green">Türen okay<br></span>';;\
\
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 = '<span style="color:red">Tür offen<br>';;\
if ($VL == 1){$ret.=' /VL'};;\
if ($VR == 1){$ret.=' /VR'};;\
if ($HL == 1){$ret.=' /HL'};;\
if ($HR == 1){$ret.=' /HR'};;\
$ret = $ret.'</span>';;\
}\
if (::ReadingsVal($car,"status_trunkOpen","true") eq "true") {\
$ret.='<span style="color:red"> Kofferraum offen</span>';;\
}\
if (::ReadingsVal($car,"status_hoodOpen","true") eq "true") {\
$ret.='<span style="color:red"> Motorhaube offen</span>';;\
}\
return $ret;;\
}\
}\
\
"$SELF"|"Kommando ".::ReadingsTimestamp("Kia_connect","status_time","")."<dd>Auswahl / Kommunikation / Tacho / Info Status</dd>" | widget([$SELF:ui_command_1],"uzsuDropDown,---,Status_getAll,car_lock,car_unlock")|(([Kia_connect:req_active] eq "idle")?'<span style="color:green">idle</span>' : '<span style="color:red">'.[Kia_connect:req_active].'</span>') |::round([Kia_connect:odometer_value],0)." km"|FUNC_Status_Laden("Kia_connect")\
\
|"Accu<dd>Steuerung / Target Soc / Accu Status</dd>" |widget([$SELF:ui_command_3],"uzsuDropDown,---,setChargeTargetSoc,stopCharge,startCharge")|"Target SOC".widget([Kia_connect:status_evStatus_reservChargeInfos_targetSOClist_2_targetSOClevel_target],"selectnumbers,50,10,100,0,lin")." %"|""| FUNC_Status([Kia_connect:range],150,"red",[Kia_connect:range],"orange",[Kia_connect:range],250,"green",[Kia_connect:range])." km"."<div style='border-width:2px;;border-style:solid;;border-color:gray;;position:relative;;width:90px;;height:20px;;background:linear-gradient( to right, red 0px,yellow 30px,green 50px);;'>".STY(" ",FUNC_batt([Kia_connect:batSOC])).STY(::round([Kia_connect:batSOC],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."</div>"\
\
|"Komfort<dd>Timer / Klima / Reifen / Türen / Accu Status 12V</dd>" |widget([$SELF:ui_timer_mode],"uzsuDropDown,Aus,heizen,kuehlen").widget([$SELF:ui_timer_Start],"time")|\
((::ReadingsVal("Abfall_Abfuhr","Kiaheizen_days",0) != 0)?"Klimatisierung<br>".[Abfall_Abfuhr:Kiaheizen_connect_date]." ".[Abfall_Abfuhr:Kiaheizen_connect_time]:(([$SELF:ui_timer_mode] ne "Aus")?"Klimatisierung<br>".[$SELF:timer_04_c04]:""))|FUNC_tire("Kia_connect")."<br>".FUNC_door("Kia_connect")|\
"12 V<div style='border-width:2px;;border-style:solid;;border-color:gray;;position:relative;;width:90px;;height:20px;;background:linear-gradient( to right, red 0px,yellow 30px,green 50px);;'>".STY(" ",FUNC_batt([Kia_connect:bat12v])).STY(::round([Kia_connect:bat12v],0)."%","font-size:16px;;position:absolute;;top:2px;;left:30px")."</div>"\
\
|"<dd> Auswahl / Temperatur / Klima Status / Temperatur innen</dd>"| 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<br>Cool".widget([Kia_connect:status_airTemp_value_target_Sommer],"selectnumbers,16,1,25,0,lin")."°C"|(([Kia_connect:status_airCtrlOn] eq "true")?'<span style="color:red">Klima läuft</span>':'<span style="color:green">Klima aus</span>')."<br>".(([Kia_connect:status_defrost] eq "true")?'Defrost ein':'Defrost aus') |"Aktuell<br>".[Kia_connect:status_airTemp_value]."°C"\
\
|"WallBox (WB_1_lp1)<dd>Lademodus / Info Status / Ladezeit / Leistung</dd>"|[WB_1:ChargeMode]."<br>".widget([$SELF:ui_command_4],"uzsuDropDown,---,SofortLaden,Min+PV,NurPV,Stop,Standby,Vorrang_EV,Vorrang_Bat,Hausspeicher_Sperren")|[WB_1:lp_1_PlugStat]." ".[WB_1:lp_1_ChargeStat]|[WB_1:lp_1_TimeRemaining]|[WB_1:lp_1_countPhasesInUse]."P ".[WB_1:lp_1_AConfigured]."A<br>".[WB_1:lp_1_W]." W"
setstate Kia_eNiro_PV 2022-01-12 13:24:24 ui_command_1 ---
setstate Kia_eNiro_PV 2022-01-10 09:18:53 ui_command_2 ---
setstate Kia_eNiro_PV 2021-11-09 07:56:54 ui_command_3 ---
setstate Kia_eNiro_PV 2022-01-12 13:02:41 ui_command_4 ---
setstate Kia_eNiro_PV 2022-01-12 13:02:41 ui_command_before_4 ---
setstate Kia_eNiro_PV 2021-11-29 09:56:58 ui_timer_Start 10:30
setstate Kia_eNiro_PV 2021-12-02 07:00:00 ui_timer_mode Aus
Kostal Plenticore mit Speicher
Zu diesem Thema gibt es noch die Wiki Seite Kostal Plenticore Plus, die alles rund um den Wechselrichter und vieles mehr erklärt. Die hier beschriebene openWB und Kia connect Anbindung bedient sich der Hausspeichersteuerung, um diesen beim Laden der BEV zu sperren. Im DOIF kann an den entsprechenden Stellen natürlich auch ein anders Kommando zum Sperren verwendet werden.