FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: igami am 16 Mai 2015, 22:13:15

Titel: userReadings neuen Wert von state
Beitrag von: igami am 16 Mai 2015, 22:13:15
Hallo zusammen,

momentan bin ich dabei mein Heimkino mit einem iTach zu erweitern. Da ich nun gerne wüsste welcher Eingang geählt ist, etc wollte ich mir mit  userReadings merker setzen.

Internals:
   CFGFN
   DEF        itach/denon_AVR_1603.txt
   FILE       itach/denon_AVR_1603.txt
   IODev      itach
   NAME       denon_AVr_1604
   NR         24886
   STATE      OFF
   TYPE       Itach_IRDevice
   CHANGETIME:
   Helper:
     Dblog:
       Input:
         Dblog:
           TIME       1431806076.18315
           VALUE      HASH(0x55cdc50)
       Power:
         Dblog:
           TIME       1431806985.60437
           VALUE      ON
       State:
         Dblog:
           TIME       1431806985.60437
           VALUE      OFF
   Readings:
     2015-05-16 22:09:45   power           ON
     2015-05-16 22:09:45   state           OFF
Attributes:
   IODev      itach
   room       ItachIR
   userReadings power {if(Value($name) ~~ ['ON','OFF']){Value($name)}}
   webCmd     ON:OFF:DVD

Wie man sieht sind die Readings 'power' und 'state' unterschiedlich. In power wird immer der wert vor dem trigger geschrieben, nicht jedoch der trigger selbst, wie ich es gerne hätte.
Wie muss ich hierbei vorgehen?

Vielen Dank und Grüße
igami
Titel: Antw:userReadings neuen Wert von state
Beitrag von: justme1968 am 16 Mai 2015, 22:47:02
das liegt am unterschied zwischen state und STATE bzw. an der reihenfolge in der readings, user readings und STATE aktualisiert werden.

Value liest STATE und das wird erst nach den user readings aktualisiert.

nimm mal statt Value(...) ReadingsVal($name,'state',''). das greift auf state zu das vorher aktualisiert wird.

wenn dein device noch mehr readings hat solltest du noch :state an den namen des user readings anhängen damit es nur von state änderungen getriggert wird und nicht  von anderen readings.

gruß
  andre
Titel: Antw:userReadings neuen Wert von state
Beitrag von: igami am 17 Mai 2015, 09:36:27
Zitat von: justme1968 am 16 Mai 2015, 22:47:02
nimm mal statt Value(...) ReadingsVal($name,'state',''). das greift auf state zu das vorher aktualisiert wird.
Das funktioniert soweit

power {if(ReadingsVal($name,'state','') ~~ ['ON','OFF']){ReadingsVal($name,'state','')}else{ReadingsVal($name,'power','')}}

nur mit dem power:state wird nicht mehr aktualisiert.

Desweiteren musste ich ja nun einen else Teil anhängen um nicht ein leeres Reading zu bekommen, wenn der Wert nicht in der Liste ist. Kann ich dies noch beeinflussen, sodass das Reading nur aktualisiert wird, wenn der Wert in der Liste steht?

Oder wäre es einfacher ein notify zu definierren, welches auf state Events von allen Itach_IRDevice triggert und dann eine entsprechende Sub aufruft?

Grüße
igami
Titel: Antw:userReadings neuen Wert von state
Beitrag von: justme1968 am 17 Mai 2015, 09:53:11
es kann sein das das anhängen mit : genau für state nicht geht.

im notify brachst du keinen else zweig. dafür kannst du ohne workaround mit sleep (siehe fommandref) keine events erzeugen um weitere notifys für die neuen readings zu verwenden.

wenn du den code etwas anders organisierst und in 99_myUtils steckst kannst du das else vermutlich auf einen einzigen fall am ende beschränken.

das notify hat aber eventuell den vorteil das es effizienter ist da insgesamt weniger code ausgeführt wird da nicht jedes unbeteiligte user reading auch ausgeführt wird.

gruß
  andre
Titel: Antw:userReadings neuen Wert von state
Beitrag von: igami am 17 Mai 2015, 11:50:12
Zitat von: justme1968 am 17 Mai 2015, 09:53:11
es kann sein das das anhängen mit : genau für state nicht geht.
Ich meine auch schon mal gelesen zu haben. dass es bei state nicht immer so einfach ist ;)

Habe es nun wie folgt gelöst:
sub iTach

sub iTach(@_){
  my ($device, $state) = @_;
  my @userreadings = split(' ', AttrVal($device, 'status', ''));

  foreach my $reading (@userreadings){
    my @values = split(':', $reading);
    $reading = $values[0];
    splice(@values, 0, 1);
    @values = split(',', $values[0]);
   
    if ($state ~~ @values){
      fhem("setreading $device $reading $state");
    }
  } 
}

meinem device die attribute

status     power:ON,OFF input:AUX,CDR/TAPE,CD,DVD,TV,V.AUX,VCR
userattr   status

hinzugefügt. Und ein notify definiert:

Internals:
   DEF        denon_AVR_1604.* {iTach($NAME,$EVENT)}
   NAME       ntfy_IRDevice
   TYPE       notify


Nun muss ich nur noch bei jedem meiner IRDevice das userattr status pflegen.

Was mir noch nicht so gefällt, ist dass ich drei mal ein split machen muss um den String passend zu trennen. Gibt es da noch einen eleganteren Weg?

Grüße
igami