MQTT2_DEVICE readingList Perl Hash-Referenz zurückgeben ?

Begonnen von TomLee, 09 Dezember 2021, 17:09:13

Vorheriges Thema - Nächstes Thema

TomLee

Hi,

Ihr übergebt in der myUtils im WLED-Thread am Ende der sub WLED_getNames eine Referenz auf einen Hash.
Das war mir bis heute nicht klar das man einfach nur die Referenz übergeben kann, für mich war die Referenz bisher die Referenz und nicht der Hash selbst.

Im Device muss man einen Hash angeben, es geht mir nur ums Verständnis, das WLED-Device ist nur misbraucht:

Zitatdefmod MQTT2_WLED_TV_test MQTT2_DEVICE WLED_538e36
attr MQTT2_WLED_TV_test userattr lightSceneParamsToSave lightSceneRestoreOnlyIfChanged:1,0
attr MQTT2_WLED_TV_test IODev MQTT2_Server
attr MQTT2_WLED_TV_test alexaName streifen
attr MQTT2_WLED_TV_test comment "http://".internalval($name,'cid','0')."\
effect:selectnumbers,0,1,115,0,lin wled/538e36/api FX=$EVTPART1\
effectname:effect.* {my $h="http://192.168.188.95/json";;$h=~s/_/-/g;; HttpUtils_NonblockingGet( {url=>"$h", callback=>sub($$$) { my ($hash, $err, $data) = @_;; $data =~ m,effects..\[([^[]*?)],;;my $s=$1;;$s=~s/"//g;;$s=~ s/\n//g;;my @a= split(/,/ , $s);;my $i = ReadingsNum($NAME,"effect","1");;;;my $an=@a;;$a=$a[$i];;fhem("setreading $NAME effectname $a;;setreading $NAME effectnumber $an")} }) }
attr MQTT2_WLED_TV_test devStateIcon {my $os = ReadingsVal($name,"LWT","offline") eq "online" ? "gruen" : "rot";;\
my $cd = Color::devStateIcon( $name, "rgb", "rgb", "brightness", "state" );;\
$cd =~ s/.*:([^:]+):.*/$1/;;\
FW_makeImage('10px-kreis-'.$os)."<a href='/fhem?cmd.dummy=set $name toggle&XHR=1'>".FW_makeImage($cd).'</a>'}
attr MQTT2_WLED_TV_test eventMap /effect 0:Solid/effect 2:Breathe/effect 63:Pride/loadPreset 1:Fire/
attr MQTT2_WLED_TV_test genericDeviceType light
attr MQTT2_WLED_TV_test group Wohnzimmer
attr MQTT2_WLED_TV_test homebridgeMapping Brightness=brightness::brightness,maxValue=100,factor=0.39216,delay=true
attr MQTT2_WLED_TV_test icon hue_filled_iris
attr MQTT2_WLED_TV_test model wled_controller
attr MQTT2_WLED_TV_test readingList wled/538e36/v:.* {{Reading1 => 7,Reading2 => 7,Reading3 => 7,Reading4 => "ggg",Reading5 => "ggg"}}
attr MQTT2_WLED_TV_test room MQTT2_DEVICE,Privat->OG->Wohnzimmer
attr MQTT2_WLED_TV_test setList on:noArg wled/538e36 on\
off:noArg wled/538e36 off\
toggle:noArg wled/538e36 t\
rgb:colorpicker,RGB wled/538e36/col #$EVTPART1\
brightness:colorpicker,BRI,0,1,255 wled/538e36\
speed:colorpicker,BRI,0,1,255 wled/538e36/api SX=$EVTPART1\
intensity:colorpicker,BRI,0,1,255 wled/538e36/api IX=$EVTPART1\
palette:selectnumbers,0,1,46,0,lin wled/538e36/api &T=1FP=$EVTPART1\
effect:knob,min:0,max:119,width:70,height:70,step:1,lineCap:round,angleOffset:180,cursor:3,thickness:.3 wled/538e36/api FX=$EVTPART1   \
loadPreset:selectnumbers,0,1,3,0,lin wled/538e36/api PL=$EVTPART1\
dimup:noArg wled/538e36/api A=~10\
dimdown:noArg wled/538e36/api A=~-10\
flash:noArg {my $v=ReadingsVal($NAME,"rgb","FFA000");;ReadingsVal($NAME,"state","off") eq "on"?fhem("set $NAME rgb FFFFFF;;sleep 0.5;;set $NAME rgb $v"):fhem("set $NAME toggle;;set $NAME rgb FFFFFF;;sleep 0.5;;set $NAME toggle")}\
effect:{"selectnumbers,0,1,".ReadingsNum($name,".effectscount",5).",0,lin"} {WLED_setName($NAME,"effect",$EVTPART1)}\
effectname:{"select,".join(",",sort(split(",",ReadingsVal($name,".effects","Solid,Police"))))} {WLED_setName($NAME,"effect",$EVTPART1)}\
palette:{"selectnumbers,0,1,".ReadingsNum($name,".palettescount",5).",0,lin"} {WLED_setName($NAME,"palette",$EVTPART1)}\
palettename:{"select,".join(",",sort(split(",",ReadingsVal($name,".palettes","Default"))))}  {WLED_setName($NAME,"palette",$EVTPART1)}
attr MQTT2_WLED_TV_test setStateList on off toggle loadPreset dimdown dimup
attr MQTT2_WLED_TV_test stateFormat LWT\ state
attr MQTT2_WLED_TV_test userReadings effectname:effect.* {WLED_getNames($name,"effect")},\
palettename:palette.* {WLED_getNames($name,"palette")}
attr MQTT2_WLED_TV_test webCmd rgb:brightness:effectname:speed:loadPreset:palettename:intensity
attr MQTT2_WLED_TV_test webCmdLabel RGB:Brightness\
:Effect:Speed:Preset\
:Palette:Intensity

setstate MQTT2_WLED_TV_test LWT\ set_toggle
setstate MQTT2_WLED_TV_test 2021-12-09 16:43:17 Reading1 7
setstate MQTT2_WLED_TV_test 2021-12-09 16:43:17 Reading2 7
setstate MQTT2_WLED_TV_test 2021-12-09 16:43:17 Reading3 7
setstate MQTT2_WLED_TV_test 2021-12-09 16:43:17 Reading4 ggg
setstate MQTT2_WLED_TV_test 2021-12-09 16:43:17 Reading5 ggg
setstate MQTT2_WLED_TV_test 2021-12-09 16:43:16 state set_toggle

Wenn ich im Device, bloss für mich zum testen, nachstellen, Erfahrung sammeln, den Hash einer Variablen zuordne und die Referenz dazu zurückgebe:
{my %cleaned = {Reading1 => 7,Reading2 => 7,Reading3 => 7,Reading4 => "ggg",Reading5 => "ggg"};return \%cleaned;}

klappt das nicht, dann steht im Log:

2021.12.09 16:40:54 1: PERL WARNING: Reference found where even-sized list expected at (eval 786043) line 1.
2021.12.09 16:40:54 3: eval: my $CID=   $evalSpecials->{'%CID'};my $DEVICETOPIC=   $evalSpecials->{'%DEVICETOPIC'};my $EVENT=   $evalSpecials->{'%EVENT'};my $EVTPART0=   $evalSpecials->{'%EVTPART0'};my $EVTPART1=   $evalSpecials->{'%EVTPART1'};my $EVTPART2=   $evalSpecials->{'%EVTPART2'};my $JSONMAP=   $evalSpecials->{'%JSONMAP'};my $NAME=   $evalSpecials->{'%NAME'};my $TOPIC=   $evalSpecials->{'%TOPIC'};{my %c ={Reading1 => 7,Reading2 => 7,Reading3 => 7,Reading4 => "ggg",Reading5 => "ggg"};;return \%c;;}


Ich verstehe das nicht, ist es was anderes wenn ich die Referenz aus der myUtils übergebe, mach ich was falsch, wo hab ich ein Verständisproblem ?

Gruß

Thomas

Beta-User

 ::) immer wieder lustig....

Also: ich komme auch an diesen Stellen immer wieder ins Schleudern, und nach meiner (nicht systematisierten) Erfahrung kommt es teils auch darauf an, welche "Siegel" man vorneanstellt und welche Klammern man nutzt, und wenn ich den Eindruck gehabt hätte, dass man das mit der myUtils ohne "Muster" vollends lösen kann, hätte ich auch den Code nicht überarbeitet...

Es gibt aber Beispiele in attrTemplate, an denen dann die Referenz übergeben wird, es scheint zu allem Überfluss auch noch darauf anzukommen, wie der Hash gefüllt wird (Suchwort in der mqtt2.template: "cleaned"), dort dann in der Regel mit "map".

Bin also auch nicht so tief drin, dass ich abschließend beantworten könnte, warum das jetzt im Detail so ist. In einem der beiden Threads zur Entwicklung der betr. attrTemplate hat Rudi mal versucht, das zu beantworten...
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

TomLee

Zitat... welche Klammern man nutzt ...

Die geschweiften Klammern um den Hash in der obigen RL hab ich verwendet weil ich auf euch vertraute das ihr es schon richtig machen würdet (die Readings werden ja auch erstellt), das runde normal für den Hash verwendet werden hatte ich im Hinterkopf, mir aber nichts weiter gedacht  nachdem ich extra nochmal in der myUtils nachgeschaut hatte und immer noch im letzten Anhang im anderen Thread umgesetzt wird.

Wenn man runde in der RL verwendet klappt das mit der Hash-Referenz, auch in der MyUtils klappt es mit runden.
Es gibt doch auch keinen Grund das es nicht klappen sollte j2nv macht doch auch nix anderes.
Ich weiß nicht was richtig ist, ob es einen Grund gibt das ihr es mit geschweiften angegangen seid und es Fälle gibt wo das nötig ist, aber die Verwendung von geschweiften in der myUtils stell ich in Frage, auch wenn die Readings erstellt werden.

Beta-User

Hmm, wie gesagt, es ist schwierig, und _eigentlich_ glaube ich, dass die geschweiften Klammern die an sich korrekte Schreibweise in Perl wären. Grundsätzlich sind geschweifte Klammern immer ein starkes Anzeichen dafür, dass es sich "eigentlich" um einen Hash handelt.

Hier funkt aber noch "AnalyzePerlCommand()" dazwischen und vorgeschaltet EvalSpecials(), und das erwartet eben als Ausgangs-Daten-Typ plain text, und keine _vorstrukturierten_ Daten. Verwendet man runde Klammern, tut man nach meinem (möglicherweise falschen!) Verständnis erst mal so, als sei das ein (in plain text notiertes) ARRAY, was sich nicht mit der EvalSpecials-Analyse beißt und erst bei der Ausführung als ARRAY aufgebaut wird, welches dann aber gleich als HASH-Liste erkannt wird, weil darin ja nur key/value-Paare enthalten sind...?

Kurz: Perl-Magie... Muß man m.E. als normaler User nicht verstehen, und in der Regel reicht es auch für die Entwicklung, wenn man den Fallstrick kennt und notfalls das richtige Siegel davorpappen kann.... Alles klar?!?
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

TomLee


TomLee

#5
Die Erläuterungen im letzten Beitrag, in einem Satz  ::), weiß ich zu schätzen und werd ich noch öfter lesen müssen in Zukunft (denk ich), hab ich im letzten Beitrag vergessen zu erwähnen.




Davon ab bleib ich dabei das wir aneinander vorbeireden was die Klammern angeht beim referenzieren.

Nach deinem letzten Beitrag hat mich die Suche nach "braces hashes" auf irgendeine Erklärung irgendwo auf stackoverflow gebracht:

  @ta = (10,20,30); # array
  $tb = [10,20,30]; # reference to an array
  %tc = (name => 'John', age => 23); # hash
  $td = {name => 'John', age => 23}; # reference to a hash


und genauso klappts auch in der RL wenn man braces nutzt, so hat man die Referenz auf den Hash (Siegel $, Klammer geschweift und greift mit  einfach nur $ darauf zurück):

wled/538e36/v:.* {my $cleaned = {Reading1 => 7,Reading2 => 7,Reading3 => 7,Reading4 => "ggg",Reading5 => "ggg"};return $cleaned;}

und ich denke das ist FHEMWEB-unabhängig.


In der myUtils verhält es sich genauso  (Siegel $, Klammer geschweift), in den if muss dann aber so verwiesen werden wie du es ganz am Anfang gezeigt hattest (mein ich):

sub WLED_getNames {
  my $dev   = shift // return;
  my $event = shift;
  my $cleaned = {api => $event};
  if ($event){
    if ( $event =~ m,(?<=<sx>)([\d]+)(?=<\/sx>),x ) {
        $cleaned->{'speed'} = $1 if $1 != ReadingsNum($dev,'speed','unknown');
    }
    if ( $event =~ m,(?<=<ix>)([\d]+)(?=<\/ix>),x ) {
        $cleaned->{'intensity'} = $1 if $1 != ReadingsNum($dev,'intensity','unknown');
    }
    if ( $event =~ m,(?<=<fp>)([\d]+)(?=<\/fp>),x ) {
        $cleaned->{'palette'} = $1 if $1 != ReadingsNum($dev,'palette','unknown');
    }
    if ( $event =~ m,(?<=<fx>)([\d]+)(?=<\/fx>),x ) {
        $cleaned->{'effect'} = $1 if $1 != ReadingsNum($dev,'effect','unknown');
    }
    if ( $event =~ m,(?<=<ps>)([\d]+)(?=<\/ps>),x ) {
        $cleaned->{'preset'} = $1 if $1 != ReadingsNum($dev,'preset','unknown');
    }
  }
  my $io = InternalVal($dev,'LASTInputDev',AttrVal($dev,'IODev',InternalVal($dev,'IODev',undef)->{NAME})) // return $cleaned;
  my $ip = InternalVal($dev,$io."_CONN",ReadingsVal($dev,'ip', undef)) =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/x ? $1 : return $cleaned;
  my $chash = $defs{$dev};
  HttpUtils_NonblockingGet({
    url=>"http://$ip/json",
    callback=>sub($$$){
      my ($hash,$err,$data) = @_;
      WLED_setReadings($dev,"effect",$1) if $data =~ m/effects..\[([^[]*?)]/x;
      WLED_setReadings($dev,"palette",$1) if $data =~ m/palettes..\[([^[]*?)]/x;
    }
  });
  return defined $event ? $cleaned : undef;
}


Mein Unverständnis liegt weiterhin beim referenzieren mit \ wenn das Siegel % verwendet wird und der myUtils evtl. iVm.  FHEMWEB <- worums mir aber zum Verständnis erstmal gar nicht geht (denk ich).

Der Hash ist und bleibt mMn. in runden Klammern zu definieren, was das referenzieren angeht ist das wieder was anderes.

TomLee

Wenn du mal Zeit hast, kannst du dir mal bitte anschauen was ich mir bis jetzt ausgedacht habe, aber noch nicht klappt, um die mehrfachen ReadingsNum Abfragen und Matches in einer Zeile abzuhandeln.

Warum wird nix in den Hash %a geschrieben, man bekommt zwar eine Referenz zurück, aber so wie ich es verstehe ist der Hash leer ?

Ich teste in der rL, der Code ist angepasst für die Kommandozeile in :

{
  my $dev   = "MQTT2_WLED_TV";;
  my $event = "ReadingsVal($dev,'api', undef)";;
    my $a = {};;
    my $h = {
speed => "m,(?<=<sx>)([\d]+)(?=<\/sx>),",
intensity => "m,(?<=<ix>)([\d]+)(?=<\/ix>),",
palette => "m,(?<=<fp>)([\d]+)(?=<\/fp>),",
effect => "m,(?<=<fx>)([\d]+)(?=<\/fx>),",
preset => "m,(?<=<ps>)([\d]+)(?=<\/ps>),"
          };;

        while ( my ($key, $value) = each (%$h)) {
        if ( $event =~ $value ) {
        return $a->{$key}=$1 if $1 != ReadingsNum($dev,$key,'unknown');;
  }}
  return $a;;
  }


Damit bekomme ich eine Hash-Referenz zurück, wenn ich das letzte return um % ergänze eine 0, daraus schliesse ich das 0 die Anzahl ist, weil ich das mit einem anderen Hash geprüft habe (mit 5 Key/Value Paaren) und dort eine fünf zurück kommt.

TomLee

Zitatm,(?<=<sx>)([\d]+)(?=<\/sx>),

sowas gehört zur korrekten Übergabe an $value in der Schleife escaped und wird mit zwei \\ dann auch übergeben, was zur Auswertung am Ende in dem Match nicht korrekt ist.

Meine Lösungsansatz ist den regexp anzupassen, bin ich aber nicht in der Lage, kann man die Zahl auch rausbekommen ohne \ zu verwenden?

OdfFhem

Statt der "Abkürzung" \d+ für eine Folge von Dezimalziffern könnte man auch [0-9]+ verwenden ...

Beta-User

Zitat von: OdfFhem am 13 Dezember 2021, 00:22:01
Statt der "Abkürzung" \d+ für eine Folge von Dezimalziffern könnte man auch [0-9]+ verwenden ...
...das ist aber nicht ganz dasselbe (sondern im europäischen Kontext meistens genauer). Wer also Probleme mit chinesischen Zahlenzeichen hat, sollte das umstellen...

Zitat von: TomLee am 12 Dezember 2021, 22:33:54
Meine Lösungsansatz ist den regexp anzupassen, bin ich aber nicht in der Lage, kann man die Zahl auch rausbekommen ohne \ zu verwenden?
Warum nicht die Logik etwas umdrehen (ungetestet):
{
  my $dev   = "MQTT2_WLED_TV";;
  my $event = "ReadingsVal($dev,'api', undef)";;
    my $c;;
    my $h = {
        sx => 'speed',
        ix => 'intensity',
        fp => 'palette,
        fx => 'effect',
        ps => 'preset'
          };;
    for (keys %{$h}) {
        next if $event !~ (?<=<$_>)([\d]+)(?=<\/$_>),";;
        $c->{$h->{$_}}=$1 if $1 != ReadingsNum($dev,$h->{$_},'unknown');;
    }
    return $c;;
}
 

Zur Vertiefung noch: Man kann uU. auch die Regex mit allen Kürzeln per pipe trennen, und dann das ganze mit einem "e", "ee" und "g" direkt in der "replace"-Anweisung eine Routine ablaufen lassen. Alles klar? Falls nicht:

regex101.com-Beispiel: "/(?'first'a+) and again (\k{first})/" (bzgl. der "hinten muss nochmal dasselbe matchen"-Frage) und https://perlmaven.com/regex-superpowers-execute-code-in-substitution zu "e" und "ee".

Enjoy...

PS: "$a" als Variablenname ist suboptimal, genauso wie "$b". Daher hier "$c"...
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

TomLee

Danke, beiden.

$c->{$h->{$_}}=$1

Kannst du Doku verlinken wo diese Schreibweise erwähnt wird, ich verstehe genau was gemacht wird, aber noch nirgendwo gelesen davon (in deinen Beiträgen/Codes schon).

Das neue Beispiel (gefällt mir) klappt so erstmal nicht, zwei kl. Fehler hab ich schon korrigiert, da sind aber noch weitere Meldungen und ich nur am Tablet, da macht das keinen Spass, beschäftige mich später am PC damit.
Und Spass macht es auch nicht wenn später schon die fertige Lösung da stehen sollte, bevor ich mich weiter mit beschäftigt habe, darum wärs nett wenn du dich mit korregieren bis zur vlt. nächsten Frage dazu zurückhältst.

Beta-User

Zitat von: TomLee am 13 Dezember 2021, 10:20:49
$c->{$h->{$_}}=$1

Kannst du Doku verlinken wo diese Schreibweise erwähnt wird, ich verstehe genau was gemacht wird, aber noch nirgendwo gelesen davon (in deinen Beiträgen/Codes schon).
Na ja, an sich ist das "ganz normale" Perl-Schreibweise, $_ ist die (namenlose) "Umlaufvariable" aus der "for"-Schleife, und dann wird halt "von innen nach außen" aufgedröselt bzw. aufgelöst...
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

TomLee

#12
Zitat von: Beta-User am 13 Dezember 2021, 10:26:05
Na ja, an sich ist das "ganz normale" Perl-Schreibweise, $_ ist die (namenlose) "Umlaufvariable" aus der "for"-Schleife, und dann wird halt "von innen nach außen" aufgedröselt bzw. aufgelöst...

Auch wenns jetzt geht, merk ich, hab ich das mit dem verweisen und "schreiben" in den Hash doch immer noch nicht richtig verstanden, es wird dir schon nicht weh tun eine deiner Meinung nach konkrete Doku zu verlinken aus der das verständlich hervorgeht  :P, hier wird bspw. gar nicht darauf eingegangen.

getestet hab ich das jetzt gleich in der rL, man muss so wie es in dem Template schon umgesetzt ist ReadingsVal verwenden weil in den Readings doch bis zu Rückmeldung das set drin steht.

attr MQTT2_WLED_TV_test readingList wled/538e36/v:.* {my $c;;my $h = {sx => 'speed',ix => 'intensity',fp => 'palette',fx => 'effect',ps => 'preset'};;for (keys %{$h}) {next if $EVENT !~ m,(?<=<$_>)([\d]+)(?=<\/$_>),;;$c->{$h->{$_}}=$1 if $1 != ReadingsVal($NAME,$h->{$_},0);;}return $c;;}

TomLee

Zitatman muss so wie es in dem Template schon umgesetzt ist ReadingsVal verwenden weil in den Readings doch bis zu Rückmeldung das set drin steht.

Es hat einen anderen Grund das ich das vermutete, es klappt zwar alles ohne Fehlermeldung aber nur wenn man als Ersatzwert auch einen numerischen Wert angibt, irgendwann in dem ganzen Ablauf (warum auch immer ) kommt der Ersatzwert zum Zuge und wenn der Text ist gibts diese Meldung:

2021.12.13 15:43:31 1: PERL WARNING: Argument "unknown" isn't numeric in numeric ne (!=) at (eval 39141) line 1.
2021.12.13 15:43:31 3: eval: my $CID=   $evalSpecials->{'%CID'};my $DEVICETOPIC=   $evalSpecials->{'%DEVICETOPIC'};my $EVENT=   $evalSpecials->{'%EVENT'};my $EVTPART0=   $evalSpecials->{'%EVTPART0'};my $EVTPART1=   $evalSpecials->{'%EVTPART1'};my $EVTPART2=   $evalSpecials->{'%EVTPART2'};my $JSONMAP=   $evalSpecials->{'%JSONMAP'};my $NAME=   $evalSpecials->{'%NAME'};my $TOPIC=   $evalSpecials->{'%TOPIC'};{my $c;;my $h = {sx => 'speed',ix => 'intensity',fp => 'palette',fx => 'effect',ps => 'preset'};;for (keys %{$h}) {next if $EVENT !~ m,(?<=<$_>)([\d]+)(?=<\/$_>),;;$c->{$h->{$_}}=$1 if $1 != ReadingsNum($NAME,$h->{$_},'unknown');;}return $c;;}

Beta-User

#14
Zitat von: TomLee am 13 Dezember 2021, 15:37:26
dir schon nicht weh tun eine deiner Meinung nach konkrete Doku zu verlinken aus der das verständlich hervorgeht  :P , hier wird bspw. gar nicht darauf eingegangen.
Na ja, ich meine, zu dieser Doku sinngemäß sowas geschrieben zu haben: Wer's deutsch will, findet da was, das auf den ersten Blick ganz ok aussieht... (Die überflüssigen Quotes sind mir aber grade auch gleich negativ ins Auge gestochen...).
Irgendwo muss man halt mal anfangen.

Wenn es numerisch sein muss, sollte man ReadingsNum() verwenden und einen numerischen Ersatzwert angeben. Dann müßte das auch klappen...

Und: Wir liegen da m.E. ziemlich tief unter dem Auto...

EDIT: Typos
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

TomLee

#15
ZitatWenn es numerisch sein muss, sollte man ReadingsNum() verwenden und einen numerischen Ersatzwert angeben. Dann müßte das auch klappen...

Zitatirgendwann in dem ganzen Ablauf (warum auch immer ) kommt der Ersatzwert zum Zuge

Bevor das untergeht, ich hab mich nicht weiter mit beschäftigt, vlt. kam das nicht so rüber, das war mehr eine Frage.

Es gibt doch keinen Grund das der Ersatzwert irgendwann genommen wird, ich sehe ihn jedenfalls noch nicht, das Reading ist doch immer vorhanden.

Es kann doch am Ende nur daran liegen das in der Schleife irgendwann mal der Verweis auf  in dem ReadingsNum nicht korrekt übergeben wird. mit der Umlaufvariablen nicht den key enthält.

Beta-User

Zitat von: TomLee am 13 Dezember 2021, 18:57:29
Es gibt doch keinen Grund das der Ersatzwert irgendwann genommen wird, ich sehe ihn jedenfalls noch nicht, das Reading ist doch immer vorhanden.
_Vermutlich_ sollte das so sein. Letztlich würde ich aber empfehlen, sich nicht einfach darauf zu verlassen, dass das ja klappen muss (die Erfahrung lehrt: was schiefgehen kann, geht irgendwann auch schief), sondern einfach - wo ohne großen Aufwand möglich - dafür zu sorgen, dass es selbst dann keine komischen Ergebnisse gibt, wenn der unmögliche Fall eingetreten ist ::) . Und ReadingsNum() "schreit" geradezu nach einem Ersatzwert (wegen der Prototypes)...
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

TomLee

#17
Ich hab mich weiter mit der Meldung

PERL WARNING: Argument "unknown" isn't numeric in numeric ne (!=)

beschäftigt, ich bin jetzt der Meinung die kommt nicht weil der Ersatzwert irgendwann mal in der Schleife genommen wird, sondern (drücks in meinen Worten aus, bin ja kein Programmierer) Perl selbst ist, aufgrund dessen das zum Vergleich != verwendet wird, in der Lage festzustellen das der angegebene Ersatzwert kein numerischer Wert ist und warnt nur das im Falle das er zum Zuge kommt nicht korrekt ist.
Nimmt man bspw. ne (mit Ersatzwert unknown,ja ich weiß ist nicht korrekt, nur zum Test) kommt die Meldung nicht.

Also sollte eigentlich alles so passen:

{my $c;my $h = {sx => 'speed',ix => 'intensity',fp => 'palette',fx => 'effect',ps => 'preset'};for (keys %{$h}) {if ($EVENT){next if $EVENT !~ m,(?<=<$_>)([\d]+)(?=<\/$_>),;$c->{$h->{$_}}=$1 if $1 ne ReadingsNum($NAME,$h->{$_},0);}};return $c;}

Beta-User

Das ist nicht "Perl selbst", das irgendwelche Eventualitäten für die Zukunft prüfen würde. Dazu müßte es wissen, was der Parameter an der Stelle soll, und wie dann die Rückgabe weiter verarbeitet wird...
Das ist ein "runtime"-Ergebnis, es ist also in der Tat irgendwas schiefgegangen. Müßte eigentlich auch am Zeitstempel zu erkennen sein.

Kann aber natürlich sein, dass das nichts sinnvolles hergibt, weil: häufig werden Eingaben in FHEM bei der Eingabe geprüft. Das ist aber eher eine formalisierte Minimalprüfung, ob das überhaupt laufen kann. Zu dem Zeitpunkt ist aber z.B. vermutlich $EVENT leer, usw., usf..
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

TomLee

Zitatvermutlich $EVENT leer

Daran hab ich auch gedacht, ob korrekt weiß ich selbst nicht genau, auf jedenfall hab ich in dem Ausführungsteil if ($EVENT) (ist auch oben in dem esit noch drin, sehe ich gerade) eingebaut gehabt, mit Ersatzwert unknown, Vergleich mit != und es kam auch zu der Meldung.
Ich bin bis jetzt noch nicht drauf gekommen warum Despee diese Prüfung eingebaut hat.

Beta-User

weiß jetzt nicht ganz genau, wo du gedanklich bist.

!= und numerischer Ersatzwert sollten immer funktionieren, und wenn man einen numerischen Wert erwartet, sollte auch numerisch gefragt/geprüft werden.
Die Prüfung an sich ist ein "eocr+"-Ersatz, also setze das Reading nur, wenn es anders ist als bisher, und verändere auch den Zeitstempel nicht.
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