[gelöst] Ergebnis aus Funktion in 99myUtils als userReading

Begonnen von Vize, 15 Oktober 2021, 14:26:15

Vorheriges Thema - Nächstes Thema

Vize

Hallo zusammen,

stehe hier mittlerweile völlig auf dem Schlauch und verzettele mich immer mehr mit meinem gefährlichen Halbwissen...
Vielleicht könnt ihr mir ein wenig helfen, oder in die richtige Richtung schubsen.

Ausgangssituation:

Device mit folgenden Readings
Betriebszustand
Betriebszustand_sub

Die Readings sind jeweils mit einer Zahl befüllt.

Der eigentliche Zustand des Gerätes (ein Pelletofen) ergibt sich aus einer Kombination dieser Zahlen und soll als Text in einem userReading angezeigt werden.
Beispiel: Wenn Betriebszustand = 1 und Betriebszustand_sub = 0, dann soll das userReading "Ofen AUS" anzeigen.

Ich möchte gerne die Ermittlung des eigentlichen Zustandes in die 99myUtils auslagern und die Funktion im userReading aufrufen, damit das Ergebnis als Text dort angezeigt wird.

Die Funktion soll grob zusammengefasst folgendes im userReading anzeigen: Wenn Variable main = 1 und Variable sub = 0 dann "Ofen AUS", wenn Variable main = 1 und Variable sub = 1 dann "Standby", wenn Variable main = 2 dann "Zündung EIN".
Es gibt noch weitere Kombinationen, aber ich wollte erstmal klein anfangen.

Nach mehreren Versuchen mit vielen Fehlermeldungen bin ich nun bei folgender Funktion mit einem "verschachtelten" if für die 99myUtils angelangt.
FHEM gibt keine Fehlermeldung oder Warnung mehr aus, aber das userReading wird leider nicht gefüllt.

sub
rika_paro_zustand ()
{
        my ($name) = @_;
my $main = ReadingsVal($name,"Betriebszustand",0);
my $sub = ReadingsVal($name,"Betriebszustand_sub",0);
if ($main == 1)
{if ($sub == 0)
{return "Ofen AUS";}
elsif ($sub == 1)
{return "Standby";}}
elsif ($main == 2)
{return "Zündung EIN";}
}


Die Funktion versuche ich so im userReading "Zustand" aufzurufen:
{rika_paro_zustand}

Wie gesagt, keine Fehlermeldung, aber das userReading bleibt leer. Ich komme im Moment leider nicht weiter und/oder sehe den Wald vor lauter Bäumen nicht...
Vielleicht kann man ja hierbei auch gar nicht mit return arbeiten?

Vielen Dank schonmal für jegliche Hilfe und Tipps!

VG
Andreas

MadMax-FHEM

#1
Also:

        my ($name) = @_;

Dann musst du schon beim Aufruf auch einen Parameter übergeben ;)

Also dann:
sub rika_paro_zustand ($)

oder ohne "Prototyp" und dann mit shift?
(ich mache es [noch immer] mit Prototyp)

Und dann eben mit dem Parameter aufrufen:

{rika_paro_zustand($name)}

Dann solltest du evtl. einen Trigger für das userReadings angeben, außer du hast nur diese beiden Readings mit auch nur 2 Events und es ist egal (oder wichtig), dass das userReadings bei jeder Änderung, egal von welchem Reading neu "berechnet" werden soll (ist hier verm. der Fall!?)...

Und dann musst du nat. warten, bis das userReadings 1x "getriggert" wurde, also bis sich mal Readings geändert haben, korrekter bis (passende) Events des Devices waren...

EDIT: und bei neuen Readings muss auch mal der Browser refreshed werden... ;)

EDIT: noch eine Anmerkung: wenn es nur Zahlen sind dann besser ReadingsNum statt ReadingsVal ;)

EDIT: man könnte das auch so machen:

sub
rika_paro_zustand ($)
{
        my ($name) = @_;
my $main = ReadingsVal($name,"Betriebszustand",0);
my $sub = ReadingsVal($name,"Betriebszustand_sub",0);
        my $ret = "Error"; # oder anderer "Defaultwert"
if ($main == 1)
{if ($sub == 0)
{$ret = "Ofen AUS";}
elsif ($sub == 1)
{$ret = "Standby";}}
elsif ($main == 2)
{$ret = "Zündung EIN";}
return $ret;
}


Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Vize

Hallo Joachim,

super, besten Dank, das waren genau die richtigen Hinweise!

Ich sach ja, Wald...Bäume...Brett...Kopf...  ;)

VG
Andreas

MadMax-FHEM

Na dann :)

Packst du noch ein [gelöst] etc. davor, danke.

EDIT: mit meiner Variante wäre es dir auch aufgefallen, denn dann hätte das userReadings bzw. die sub ja "Error" zurückgegeben ;)

Viel Spaß noch, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Vize


betateilchen

Das Ganze könnte man natürlich noch perfomanter gestalten, indem man sich die (für mein Empfinden zu vielen) logischen Vergleiche nochmal zu Gemüte führt und ggf. optimiert.

Dazu bräuchte man aber ein paar mehr Informationen.


  • welche Werte sind überhaupt für main möglich?
  • welche Werte sind überhaupt für sub möglich?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Vize

Hallo betateilchen,

vielen Dank für deine Anmerkung.

Das ganze Konstrukt sieht nun so aus:

sub
rika_paro_zustand ($)
{
my ($name) = @_;
my $main = ReadingsNum($name,"Betriebszustand",0);
my $sub = ReadingsNum($name,"Betriebszustand_sub",0);
my $ret = "unbekannt";
  if ($main == 1)
   {
   if ($sub == 0)
    {$ret = "Ofen AUS";}
   elsif ($sub == 1)
    {$ret = "Standby";}
   elsif ($sub == 2)
    {$ret = "Externe Anforderung";}
   elsif ($sub == 3)
    {$ret = "Standby";}
   }
  elsif ($main == 2)
   {$ret = "Zündung EIN";}
  elsif ($main == 3)
   {$ret = "Startphase";}
  elsif ($main == 4)
   {$ret = "Regelbetrieb";}
  elsif ($main == 5)
   {
   if (($sub == 3) || ($sub == 4))
    {$ret = "Gr. Reinigung";}
   else {$ret = "Reinigung";}
   }
  elsif ($main == 6)
   {$ret = "Ausbrand";}
  elsif (($main == 11) || ($main == 13) || ($main == 14) || ($main == 16) || ($main == 17) || ($main == 50))
   {$ret = "Scheitholzcheck";}
  elsif (($main == 20) || ($main == 21))
   {$ret = "Scheitholzbetrieb";}
return $ret;
}


Es gibt - glaube ich - noch zwei weiter main-states mit ein oder zwei sub-states, die ich aber nicht brauche.

Unter if ($main == 1) könnte man sicher noch die beiden "Standby" zusammenfassen. Vielleicht kann man auch noch die ganzen oder-Abfragen zusammenfassen und/oder performanter gestalten?

VG
Andreas

betateilchen

Mein Ansatz wäre ein ganz anderer: Ich würde einen hash mit den key->value Paaren anlegen und daraus die entsprechenden Werte auslesen.

Was steht in $sub, wenn $main z.B. 2 oder 3 ist und von Dir gar nicht geprüft wird?

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Vize

Moin,

wenn in $main 2, 3, 4, 6, 11, 13, 14, 16, 17, 50, 20 oder 21 steht, ist es wurscht, was in $sub steht.
Dann zählt zur Ermittlung des korrekten Zustandes nur das, was von $main zurückgegeben wird.

Hier mal ein Auszug aus dem Quelltext der website mit den Stati:
if (mainState == 1) {
        if (subState == 0)
            return ["/images/status/Visu_Off.svg", "Ofen AUS"];
        else if (subState == 1)
            return ["/images/status/Visu_Standby.svg", "Standby"];
        else if (subState == 2)
            return ["/images/status/Visu_Standby.svg", "Externe Anforderung"];
        else if (subState == 3)
            return ["/images/status/Visu_Standby.svg", "Standby"];
        return ["/images/status/Visu_Off.svg", "Substate unbekannt"];
    }
    else if (mainState == 2)
        return ["/images/status/Visu_Ignition.svg", "Zündung EIN"];
    else if (mainState == 3)
        return ["/images/status/Visu_Ignition.svg", "Startphase"];
    else if (mainState == 4) {
        if (bakeMode && tempDiff < 10)
            return ["/images/status/Visu_Bake.svg", "Backen"];
        else if (bakeMode)
            return ["/images/status/Visu_HeatingUp.svg", "Aufheizen"];
        else
            return ["/images/status/Visu_Control.svg", "Regelbetrieb"];
    }
    else if (mainState == 5) {
        if (subState == 3 || subState == 4)
            return ["/images/status/Visu_Clean.svg", "Gr. Reinigung"];
        else
            return ["/images/status/Visu_Clean.svg", "Reinigung"];
    }
    else if (mainState == 6)
        return ["/images/status/Visu_BurnOff.svg", "Ausbrand"];
    else if (mainState == 11 || mainState == 13 || mainState == 14 || mainState == 16 || mainState == 17 || mainState == 50)
        return ["/images/status/Visu_SpliLog.svg", "Scheitholzcheck"];
    else if (mainState == 20 || mainState == 21)
        return ["/images/status/Visu_SpliLog.svg", "Scheitholzbetrieb"];
    return ["/images/status/Visu_Off.svg", "Unbekanntes Problem"];


VG
Andreas


betateilchen

Zitat von: Vize am 17 Oktober 2021, 12:31:05
wenn in $main 2, 3, 4, 6, 11, 13, 14, 16, 17, 50, 20 oder 21 steht, ist es wurscht, was in $sub steht.
Dann zählt zur Ermittlung des korrekten Zustandes nur das, was von $main zurückgegeben wird.

Ok, ich hab keine Lust, jetzt nochmal nachzufragen.
Wenn Du meinst, jeder meiner Fragen mit einer sinnfreien Antwort begegnen zu müssen und Du mit Deiner jetzigen (für mich abstrusen) Lösung zufrieden bist, dann soll es halt so sein.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Beta-User

...offenbar sind User schon gerne mal überfordert, wenn man "Hash-lookup" erwähnt...

Diese (völlig unnötigen) elsif-Bandwürmer sind echt grausam.

@Vize: Vielleicht schaust du mal zu einem ganz ähnlichen Fall zum einen in den (ungetesteten) Code aus https://forum.fhem.de/index.php/topic,104968.msg1180136.html#msg1180136 rein, und zum anderen in den aus dem vorherigen Post.

Funktional sollte beides (fast) gleich sein, und diese langen Listen sind für sich genommen auch grausam, aber das eine sollte man lesen können, und das andere, ... na ja, funktioniert vermutlich...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files