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
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
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
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
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