Hallo zusammen,
ich habe mir mit ModBusAttr eine Anbindung an meinen SolarEdge Wechselrichter gebastelt und würde für die Umschaltung zwischschen den Betriebsarten statt eines DropDowns, das ich mit WidgetOverride mit den numerischen Werten erstellen kann, in der Anzeige "sprechende" Betriebsarten stehen haben, so wie das in HTML auch der Fall ist, also statt
1
2
3
4
dann
Ein
Aus
Eco
Max
was dann auf die Werte 1 bis 4 mappt.
Ich weiß, dass das über den Umweg mit Dummys, notifies und DOIFs ginge, aber für den reinen Austausch der Anzeige hoffe ich doch, dass es da ohne das Anlegen von einer Handvoll weiterer Geräte eine Lösung gibt?
VG, F.
Vermutlich geht das schon mit etwas eventMap und webCmd, (und ggf. cmdIcon etc...).
"In der Anzeige" kann man mit STATE übersetzen? Dann würde ggf. auch ein "einfaches (Perl-?) stateFormat" helfen. Ein (raw)-Listing und eine Skizze, wie du dir das in etwa denkst würden ggf. helfen...
Danke für die Rückmeldung!
Hier erst einmal das raw listing des Devices:
defmod BydBattery ModbusAttr 1 10 192.168.1.132:502 TCP
attr BydBattery DbLogExclude .*
attr BydBattery dev-h-combine 1
attr BydBattery dev-h-defPoll 1
attr BydBattery dev-h-defShowGet 1
attr BydBattery disable 0
attr BydBattery event-on-change-reading .*
attr BydBattery obj-h40083-reading Power_Ac
attr BydBattery obj-h40083-unpack s>
attr BydBattery obj-h40084-reading Power_Ac_Scale
attr BydBattery obj-h40084-unpack s>
attr BydBattery obj-h40206-reading Meter_Power
attr BydBattery obj-h40206-unpack s>
attr BydBattery obj-h40210-reading Meter_Power_Scale
attr BydBattery obj-h40210-unpack s>
attr BydBattery obj-h57348-reading Storage_Control_Mode
attr BydBattery obj-h57348-set 1
attr BydBattery obj-h57352-len 2
attr BydBattery obj-h57352-reading Storage_Backup_Reserved_Setting
attr BydBattery obj-h57352-revRegs 1
attr BydBattery obj-h57352-set 1
attr BydBattery obj-h57352-unpack f>
attr BydBattery obj-h57354-reading Storage_Charge-Discharge_Default_Mode
attr BydBattery obj-h57354-set 1
attr BydBattery obj-h57355-len 2
attr BydBattery obj-h57355-reading Rc_Cmd_Timeout
attr BydBattery obj-h57355-revRegs 1
attr BydBattery obj-h57355-set 1
attr BydBattery obj-h57355-unpack l>
attr BydBattery obj-h57357-reading Rc_Cmd_Mode
attr BydBattery obj-h57357-set 1
attr BydBattery obj-h57666-len 2
attr BydBattery obj-h57666-reading Battery_Capacity
attr BydBattery obj-h57666-revRegs 1
attr BydBattery obj-h57666-unpack f>
attr BydBattery obj-h57716-len 2
attr BydBattery obj-h57716-reading Battery_Instantaneous_Power
attr BydBattery obj-h57716-revRegs 1
attr BydBattery obj-h57716-unpack f>
attr BydBattery obj-h57732-len 2
attr BydBattery obj-h57732-reading Battery_SoE
attr BydBattery obj-h57732-revRegs 1
attr BydBattery obj-h57732-unpack f>
attr BydBattery oldreadings pvProduction
attr BydBattery openTimeout 10
attr BydBattery room Solar
attr BydBattery silentReconnect 1
attr BydBattery skipGarbage 1
attr BydBattery stateFormat Battery_SoE
attr BydBattery userReadings kWp {5920},\
adjustment_factor {ReadingsVal($NAME,"adjustment_factor",0.7)},\
min_battery_level {ReadingsVal($NAME,"min_battery_level",20)},\
\
avg_consumption_counter:Meter_Power.* {\
ReadingsVal($NAME,"avg_consumption_counter",0)+1;;\
},\
\
avg_consumption_sum:Meter_Power.* {\
ReadingsVal($NAME,"avg_consumption_sum",0) + ReadingsVal($NAME, "householdConsumption", 0);;\
},\
\
avg_consumption:Meter_Power.* {\
my $acs = ReadingsVal($NAME,"avg_consumption_sum",0);;\
my $acc = ReadingsVal($NAME, "avg_consumption_counter", 0);;\
if ($acc > 0) {\
return sprintf("%.1f", $acs / $acc);;\
} else {\
return 0;;\
} \
},\
\
avg_production_counter:Meter_Power.* {\
ReadingsVal($NAME,"avg_production_counter",0)+1;;\
},\
\
avg_production_sum:Meter_Power.* {\
ReadingsVal($NAME,"avg_production_sum",0) + ReadingsVal($NAME, "pvProduction",0);;\
},\
\
avg_production:Meter_Power.* {\
my $aps = ReadingsVal($NAME,"avg_production_sum",0);;\
my $apc = ReadingsVal($NAME, "avg_production_counter", 0);;\
if ($apc > 0) {\
return sprintf("%.1f", $aps/$apc);;\
} else {\
return 0;;\
}\
},\
\
householdConsumption {\
my $pA = ReadingsVal($NAME, "Power_Ac", 0) * (10 ** ReadingsNum ($NAME, "Power_Ac_Scale", 0));;\
my $hC = $pA - ReadingsVal($NAME, "gridImportExport", 0);; \
my $pP = $pA + ReadingsVal($NAME, "Battery_Instantaneous_Power", 0);;\
if ($pP < 0) {\
$hC = $hC + abs($pP);;\
}\
return $hC;;\
},\
\
batteryNeeded {\
my $v = ReadingsVal($NAME, "Battery_Capacity", 0);; \
return ($v - ($v * ReadingsVal ($NAME, "Battery_SoE", 1) / 100))\
},\
\
gridImportExport {\
ReadingsVal($NAME, "Meter_Power", 0) * (10 ** ReadingsNum ($NAME , "Meter_Power_Scale", 0))\
},\
\
post_peak:Meter_Power.* {\
my $fc = ReadingsVal("SolCast","forecast_today",0);;\
my $fc_old = OldReadingsVal("SolCast","forecast_today",0);;\
my $af = ReadingsVal($NAME,"adjustment_factor",1);;\
my $bn = ReadingsVal($NAME,"batteryNeeded",1);;\
my $pp = ReadingsVal($NAME,"post_peak",0);;\
if (($fc*$af > $bn && $pp == 0) || ($fc_old <= 0 && $fc > 0)) {\
return 0;;\
} else {\
return 1;;\
}\
},\
\
pvProduction {\
my $kWp = ReadingsVal($NAME, "kWp", 0);;\
my $PAc = ReadingsVal($NAME, "Power_Ac", 0);;\
my $PAS = ReadingsNum ($NAME, "Power_Ac_Scale", 0);;\
my $BIP = ReadingsVal($NAME, "Battery_Instantaneous_Power", 0);;\
my $pP = $PAc * (10 ** $PAS) + $BIP;;\
my $pP_old = OldReadingsVal($NAME, "pvProduction", 0);;\
if ($pP < 0) {\
$pP = 0;;\
}\
if ($pP > $kWp) {\
$pP = $pP_old;;\
}\
return $pP;;\
},\
\
forecast_today_old:Meter_Power.* {\
OldReadingsVal("SolCast", "forecast_today", -1);;\
},\
forecast_today:Meter_Power.* {\
ReadingsVal("SolCast", "forecast_today", -1);;\
},\
\
attr BydBattery widgetOverride Rc_Cmd_Mode:uzsuDropDown,1,2,3,4,5,7
setstate BydBattery 32
setstate BydBattery 2021-09-03 23:09:33 Battery_Capacity 4000
setstate BydBattery 2021-09-03 23:09:33 Battery_Instantaneous_Power -380
setstate BydBattery 2021-09-03 23:09:34 Battery_SoE 32
setstate BydBattery 2021-09-03 23:09:32 Meter_Power -23
setstate BydBattery 2021-09-03 23:09:32 Meter_Power_Scale 0
setstate BydBattery 2021-09-03 23:09:32 Power_Ac 28200
setstate BydBattery 2021-09-03 23:09:32 Power_Ac_Scale -2
setstate BydBattery 2021-09-03 23:09:33 Rc_Cmd_Mode 7
setstate BydBattery 2021-09-03 23:09:33 Rc_Cmd_Timeout 3600
setstate BydBattery 2021-09-03 23:09:33 Storage_Backup_Reserved_Setting 0
setstate BydBattery 2021-09-03 23:09:33 Storage_Charge-Discharge_Default_Mode 7
setstate BydBattery 2021-09-03 23:09:33 Storage_Control_Mode 4
setstate BydBattery 2021-09-03 23:09:34 adjustment_factor 0.7
setstate BydBattery 2021-09-03 23:09:32 avg_consumption 495.1
setstate BydBattery 2021-09-03 23:09:32 avg_consumption_counter 7883
setstate BydBattery 2021-09-03 23:09:32 avg_consumption_sum 3903248.2
setstate BydBattery 2021-09-03 23:09:32 avg_production 0.0
setstate BydBattery 2021-09-03 23:09:32 avg_production_counter 10
setstate BydBattery 2021-09-03 23:09:32 avg_production_sum 0
setstate BydBattery 2021-09-03 23:09:34 batteryNeeded 2720
setstate BydBattery 2021-09-03 23:09:32 forecast_today -1487.1
setstate BydBattery 2021-09-03 23:09:32 forecast_today_old -1738.45
setstate BydBattery 2021-09-03 23:09:34 gridImportExport -23
setstate BydBattery 2021-09-03 23:09:34 householdConsumption 403
setstate BydBattery 2021-09-03 23:09:34 kWp 5920
setstate BydBattery 2021-09-03 23:09:34 min_battery_level 30
setstate BydBattery 2021-09-03 23:09:32 post_peak 1
setstate BydBattery 2021-09-03 23:09:34 pvProduction 0
setstate BydBattery 2021-09-03 22:09:22 state opened
Mit "in der Anzeige" meinte ich die Zeile, die in der Device-Übersicht angezeigt wird - ja, das wird wohl STATE sein.
Mit widgetOverride bekomme ich den Eintrag jetzt neben den set-Befehl, aber eben auch da nur numerisch, weil der Wert ja numerisch ist. Statt 1,2,3... möchte ich halt "Klartext" dort stehen haben, per Dropdown auswählen können, damit dann der enstprechende numerische Wert gesetzt wird. Und das im angehängten Screenshot nicht da, wo jetzt das Dropdown ist, sondern da, wo die "31" steht, also im STATE.
In HTML wäre das vergleichbar mit
<select name="Rc_Cmd_Mode">
<option value=0>Aus</option>
<option value=1>Ein</option>
</select>
Dass ich mir mit stateFormat einen Text statt einer Zahl anzeigen lassen kann, ist mir schon bekannt, aber das geht m.W. ja nur lesend. Kann ich das auch schreibend in Form eines Dropdowns machen? Das wäre natürlich super!
Kann sein, dass es nicht klappt, aber leider habe ich kein passendes Gerät:
attr BydBattery eventMap /Rc_Cmd_Mode 1:Rc_Cmd_Mode Ein/Rc_Cmd_Mode 2:Rc_Cmd_Mode Aus/Rc_Cmd_Mode 3:Rc_Cmd_Mode Eco/Rc_Cmd_Mode 4:Rc_Cmd_Mode Max/
attr BydBattery webCmd Rc_Cmd_Mode
attr BydBattery widgetOverride Rc_Cmd_Mode:uzsuDropDown,Ein,Aus,Eco,Max,5,7
Hatte versucht, das an einem dummy nachzustellen, und dann Probleme gehabt, wenn es den Eintrag auch in der readingList gab.
Blöd ist halt, dass das hier rein nummerisch ist, nur die Ziffern abzugreifen könnte möglich sein, wenn man "usr=> ..." (und (?) "fw=>...") eventMap setzt (die commandref-Auszüge müßten bei neuen FHEM-Versionen erscheinen, wenn man das Attribut in der Detailansicht auswählt).
Btw.: die userReadings sind teils auch ohne trigger, und um einen festen Wert vorzugeben, braucht es eigentlich auch nur ein einmaliges "setreading ..."
PS: FHEM ist mir abgeschmiert, als ich das RAW-Device (angelegt mit "none" als Zieladresse) wieder gelöscht habe:
ZitatCan't use an undefined value as an ARRAY reference at ./FHEM/98_Modbus.pm line 3325.
Hab's nicht näher untersucht...
Klasse, vielen Dank!
Es klappt schon fast so, wie ich mir das vorstelle: Das Dropdown erscheint oben, die Werte werden entsprechenden Texten zugeordnet und ich sehe, dass das Reading kurzzeitig auf den gewünschten numerischen Wert springt, dann aber sofort wieder auf den unter widgetOverride zuletzt genannten Wert springt.
Zuerst dachte ich, dass das mit einem zugehörigen DOIF zusammenhängt, aber auch wenn ich dieses disable bleibt es so. Wenn ich hingegen über die set-Zeile den Wert ändere, bleibt er so.
Hast Du eine Ahnung, woran das liegen könnte, bzw. wie man das beheben könnte?
Hmm, der Effekt klingt nach dem, was ich mir dem dummy auch hatte.
_Vielleicht_ läßt sich das vermeiden, wenn man einen "Pseudo-Command" erzeugt und den mappt.
Also als Startpunkt sowas:
attr BydBattery webCmd Modus
attr BydBattery widgetOverride Modus:uzsuDropDown,Ein,Aus,Eco,Max,5,7
Und dazu ein "einseitige mapping" (in der usr=>-Variante, da könnte/müsste dann Ein=>1 als Eintrag reichen).
Ein Reading "Rc_Cmd_Mode" gibt/gab es nicht, oder übersehe ich was?
Ok, danke, dann probiere ich mal was in der Richtung...
Rc_Cmd_Mode gibt es weiter oben in der Zeile:
attr BydBattery obj-h57357-reading Rc_Cmd_Mode
Und eine letzte Frage, leicht OT: Ich weiß, dass Leerzeichen in FHEM nicht gern gesehen sind, aber kann ich diese trotzdem irgendwie in der widgetOverride Darstellung verwenden?
Ein, Aus etc. waren nur Beispielwerte, wenn ich nun "Maximize self-consumption" darstellen möchte, klappt das nur mit Unterstrich. Schöner wäre es, wenn in dem Auswahlmenü Leerzeichen angezeigt werden könnten (evtl. mit ? Aber da weiß ich nicht, ob das & dann in Perl Probleme macht)
_Vielleicht_ geht das mit einem "+" statt des Leerzeichens in der Widget-Definition
Danke, aber das "+" wird dann direkt als Plus angezeigt. Mit sieht es gut aus, allerdings klappt es dann mit der eventMap nicht mehr (wo ich das natürlich auch entsprechend angepasst habe). Da kommt dann die Fehlermeldung:
"Set Value Export from battery is not numeric and textArg not specified"
OK, das hatte ich dann falsch aus "devStateIcon" im Kopf, sorry.
"Im Prinzip" müßte das alles irgendwie gehen, aber vermutlich führt das über relativ komplexen Code in devStateIcon. Nicht erschrecken, aber evtl. hilft da der sonos2mqtt-Code weiter? Da gibt es relativ viele "spezielle" setter, die da reingeknödelt wurden...
Danke, ist auch nicht so schlimm, nur falls es einen Weg gäbe, der mir nicht bekannt ist, wäre ich den gerne gegangen. Den sonos2mqtt Client kann ich mir dann bei Gelegenheit aber mal anschauen, danke für den Tipp!
Dann versuche ich mich die Tage mal mit der usr-Geschichte und würde mich ggf. noch mal melden, wenn ich es nicht hinbekomme?
Gerne.
Wobei ich vermute, dass es einfacher wäre, die Visualisierung über andere Methoden zu machen (readingsGroup wäre mein Favorit, evtl. ginge auch ui_Table aus DOIF, aber mit letzterem kenne ich mich nicht aus)....
Hier die angesprochene Lösung mit uiTable als Beispiel:
defmod di_dropdown DOIF {set_State([$SELF:mode])}\
{if ([$SELF:mode] eq "Ein") {\
fhem_set "bla 1"\
} elsif ([$SELF:mode] eq "Aus") {\
fhem_set "bla 2"\
} elsif ([$SELF:mode] eq "Eco") {\
fhem_set "bla 3"\
} elsif ([$SELF:mode] eq "Max") {\
fhem_set "bla 4"\
}\
}
attr di_dropdown uiTable {package ui_Table}\
\
"Auswahl"|widget([$SELF:mode],"uzsuDropDown,Ein,Aus,Eco,Max")
Das lässt sich ebenfalls eleganter mit Arrays oder hash statt mit if-elseif-Zweigen realisieren, wenn man über bestimmte Perlkenntnisse verfügt.
Man kann ebenfalls die Auswahl im Status des Moduls über setList, readingsList und webcmd realisieren.
Der Vorteil dieser Lösung:
- Alles in einem Modul
-uiTable beliebig erweiterbar für weitere Visualisierungen https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg,
- beliebiger Perlcode zum Steuern von Devices abhängig von der Auswahl https://wiki.fhem.de/wiki/DOIF/Automatisierung
Danke, das sieht ja auch sehr gut aus!
Nur noch mal für mein Verständnis: Warum kommt es denn bei der von Beta-User genannten Lösung zu der nur kurzzeitigen Änderung und dann dem Sprung, wenn man es über das widgetOverride-Dropdown ändert, aber nicht, wenn ich es über das Dropdown beim beim set ändere?
Das Problem scheint zu sein, dass nach der Auswahl das DropDown neu aufgebaut wird und dann kein richtiges Matching zum eingestellten Wert erfolgt, sondern immer der letzte Eintrag ausgewählt wird, der dann gleich neu gesetzt wird. Warum das nur bei der widgetOverride-Zeile der Fall ist und nicht in der set-Zeile, ist mir aber nicht erklärlich...
EDIT: Ich habe eine Lösung gefunden.
Wenn man in dem Ausgelösten DOIF Zweig das auslösende reading "ui_command" mit z.B. "---" neu setzt,
dann kann man es im pull down Menü direkt mehrfach auswählen und es wird jedes mal ein frischer Event erzeugt.
Zitat von: Damian am 04 September 2021, 10:51:45
Hier die angesprochene Lösung mit uiTable als Beispiel:
defmod di_dropdown DOIF {set_State([$SELF:mode])}\
{if ([$SELF:mode] eq "Ein") {\
fhem_set "bla 1"\
} elsif ([$SELF:mode] eq "Aus") {\
fhem_set "bla 2"\
} elsif ([$SELF:mode] eq "Eco") {\
fhem_set "bla 3"\
} elsif ([$SELF:mode] eq "Max") {\
fhem_set "bla 4"\
}\
}
attr di_dropdown uiTable {package ui_Table}\
\
"Auswahl"|widget([$SELF:mode],"uzsuDropDown,Ein,Aus,Eco,Max")
Das lässt sich ebenfalls eleganter mit Arrays oder hash statt mit if-elseif-Zweigen realisieren, wenn man über bestimmte Perlkenntnisse verfügt.
Man kann ebenfalls die Auswahl im Status des Moduls über setList, readingsList und webcmd realisieren.
Der Vorteil dieser Lösung:
- Alles in einem Modul
-uiTable beliebig erweiterbar für weitere Visualisierungen https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg,
- beliebiger Perlcode zum Steuern von Devices abhängig von der Auswahl https://wiki.fhem.de/wiki/DOIF/Automatisierung
Hey Damian,
Du hattest mir diese Tage ja bereits auch den Tip mit uiTable gegeben und ich habe dieses Beispiel in mein DDIF eingebaut.
Das sieht soweit auch gut aus, danke dafür.
Leider kann ich damit einen Event nur einmal ausführen. Danach muss ich erst etwas anderes auswählen, um dann wieder das gewünschte zu selektieren.
Kann ich es so konfigurieren, dass ich den selben Eintrag mehrfach auswähle und es jedes mal einen Event auslöst?
EDIT: Das DOIF Attribut "do always" ist übrigens bereits gesetzt.
uiTable
{package ui_Table}
"Kommando"|widget([$SELF:ui_command],"uzsuDropDown,smart_Laden start,smart_Laden beenden,3 Minuten Wiederholung")
Im DOIF ist es dann so...
<...>
################################################################################################################
## 6 Wiederhole alle 180s die Kommandos der ExternControl Steuerung
##
DOELSEIF
([$SELF:ui_command] eq "3 Minuten Wiederholung" or
[WR_1_API:Battery_Control] > 0 and ## Wenn die ExternControl am WR konfiguriert ist
[$SELF:SpeicherCmdRepeatActive] == 1 and ## Wenn die ExternControl Aktiviert ist
[$SELF:SpeicherCmdRepeatRunning] == 1 and ## Wenn es ExternControl Kommandos zum Senden gibt
[ {sunrise_abs("HORIZON=+5.0",0,"6:00","08:35")}
- {sunset_abs("HORIZON=+8.0",0,"15:00","21:00")} ] and [+180] ) ## alle 3 Minuten den Befehl wiederholen
{
<...>
VG
Christian
ZitatLeider kann ich damit einen Event nur einmal ausführen. Danach muss ich erst etwas anderes auswählen, um dann wieder das gewünschte zu selektieren.
Kann ich es so konfigurieren, dass ich den selben Eintrag mehrfach auswähle und es jedes mal einen Event auslöst?
Das liegt wohl am widget selbst - das liegt allerdings nicht in meiner Hand.
Zitat von: Damian am 08 September 2021, 19:57:39
Das liegt wohl am widget selbst - das liegt allerdings nicht in meiner Hand.
Ich habe hier ja schon eine Lösung gefunden :-)
Zitat
EDIT: Ich habe eine Lösung gefunden.
Wenn man in dem Ausgelösten DOIF Zweig das auslösende reading "ui_command" mit z.B. "---" neu setzt,
dann kann man es im pull down Menü direkt mehrfach auswählen und es wird jedes mal ein frischer Event erzeugt.
<...>
################################################################################################################
## 6 Wiederhole alle 180s die Kommandos der ExternControl Steuerung
##
DOELSEIF
([$SELF:ui_command] eq "3 Minuten Wiederholung" or
[WR_1_API:Battery_Control] > 0 and ## Wenn die ExternControl am WR konfiguriert ist
[$SELF:SpeicherCmdRepeatActive] == 1 and ## Wenn die ExternControl Aktiviert ist
[$SELF:SpeicherCmdRepeatRunning] == 1 and ## Wenn es ExternControl Kommandos zum Senden gibt
[ {sunrise_abs("HORIZON=+5.0",0,"6:00","08:35")}
- {sunset_abs("HORIZON=+8.0",0,"15:00","21:00")} ] and [+180] ) ## alle 3 Minuten den Befehl wiederholen
{
CommandSetReading(undef, "$SELF ui_command ---"); ## <<<<<<< Das setzt das reading nach dem Ausführen wieder zurück
my $MaxChargePowerTime = 0;
my $MaxChargePowerAbs_midday = 0;
<...>
Das läuft schon mal super, bis auf das hier (https://forum.fhem.de/index.php/topic,122866.0.html)