############################################## # $Id$ package main; use strict; use warnings; use vars qw($FW_ME); # webname (default is fhem) ##################################### sub readingsChange_Initialize($) { my ($hash) = @_; $hash->{DefFn} = "readingsChangeDefine"; $hash->{NotifyFn} = "readingsChangeExec"; $hash->{AttrList} ="disable:1,0 disabledForIntervals addStateEvent:1,0"; $hash->{NotifyOrderPrefix} = "00-"; # be the first } ##################################### sub readingsChangeDefine($$) { my ($hash, $def) = @_; my ($name, $type, @re) = split("[ \t]+", $def, 6); return "Usage: define readingsChange ". " " if(int(@re) != 4); $hash->{".re"} = \@re; # Checking for misleading regexps for(my $idx = 0; $idx < 3; $idx++) { my $re = $re[$idx]; return "Bad regexp: starting with *" if($re =~ m/^\*/); eval { "Hallo" =~ m/^$re$/ }; return "Bad regexp $re: $@" if($@); } if($re[3] =~ m/^{.*}/) { $hash->{".isPerl"} = 1; my %specials= (); my $err = perlSyntaxCheck($re[3], %specials); return "$re[3]: $err" if($err); } readingsSingleUpdate($hash, "state", "active", 0); notifyRegexpChanged($hash, $re[0]); return undef; } ##################################### sub readingsChangeExec($$) { my ($rc, $dev) = @_; my $SELF = $rc->{NAME}; return "" if(IsDisabled($SELF)); my $re = $rc->{".re"}; my $NAME = $dev->{NAME}; return if($NAME !~ m/$re->[0]/ || !$dev->{READINGS}); my $events = deviceEvents($dev, AttrVal($SELF, "addStateEvent", 0)); return if(!$events); my $max = int(@{$events}); my $matched=0; for (my $i = 0; $i < $max; $i++) { my $EVENT = $events->[$i]; next if(!defined($EVENT) || $EVENT !~ m/^([^ ]+): (.+)/); my ($rg, $val) = ($1, $2); next if($rg !~ m/$re->[1]/ || !$dev->{READINGS}{$rg}); Log3 $SELF, 5, "Changing $NAME:$rg $val via $SELF"; $matched++; if($rc->{".isPerl"}) { eval "\$val =~ s/$re->[2]/$re->[3]/ge"; } else { eval "\$val =~ s/$re->[2]/$re->[3]/g"; } $events->[$i] = "$rg: $val"; $dev->{READINGS}{$rg}{VAL} = $val; } evalStateFormat($dev) if($matched); return undef; } 1; =pod =item helper =item summary modify reading value upon change =item summary_DE Reading-Werte modifizieren bei Änderung =begin html

readingsChange


    Define
      define <name> readingsChange <device> <readingName> <toReplace> <replaceWith>"

      Change the content of a reading if it changes, with the perl string substitute mechanism. Note: As some modules rely on the known format of some readings, changing such readings may cause these modules to stop working.

      <device>, <readingName> and <toReplace> are regular expressions, and are not allowed to contain whitespace. If replaceWith is enclosed in {}, then the content will be executed as a perl expression for each match.
      Notes:
      • after a Reading is set by a module, first the event-* attributes are evaluated, then userReadings, then stateFormat, then the readingsChange definitions (in alphabetical order), and after this the notifies, FileLogs, etc. again in alphabetical order.
      • if stateFormat for the matched device is set, then it will be executed multiple times: once before the readingsChange, and once for every matching readingsChange.


      Examples:
        # shorten the reading power 0.5 W previous: 0 delta_time: 300
        # to just power 0.5 W
        define pShort readingsChange pm power (.*W).* $1

        # format each decimal number in the power reading to 2 decimal places
        define p2dec readingsChange pm power (\d+\.\d+) {sprintf("%0.2f", $1)}

    Set
      N/A

    Get
      N/A

    Attributes
=end html =cut