mirror of
https://github.com/fhem/fhem-mirror.git
synced 2024-06-17 05:40:11 +00:00
![rudolfkoenig](/assets/img/avatar_default.png)
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@23471 2b470e98-0d58-463d-a4d8-8e2adae1ed80
290 lines
7.2 KiB
Perl
290 lines
7.2 KiB
Perl
##############################################
|
|
# $Id$
|
|
package main;
|
|
use IO::File;
|
|
|
|
use strict;
|
|
use warnings;
|
|
sub et_addEvt($$$$);
|
|
|
|
#####################################
|
|
sub
|
|
eventTypes_Initialize($)
|
|
{
|
|
my ($hash) = @_;
|
|
|
|
$hash->{DefFn} = "eventTypes_Define";
|
|
$hash->{NotifyFn} = "eventTypes_Notify";
|
|
$hash->{ShutdownFn}="eventTypes_Shutdown";
|
|
$hash->{UndefFn} = "eventTypes_Undef";
|
|
$hash->{GetFn} = "eventTypes_Get";
|
|
$hash->{SetFn} = "eventTypes_Set";
|
|
$hash->{AttrFn} = "eventTypes_Attr";
|
|
$hash->{AttrList} = "disable:0,1 ignoreList";
|
|
}
|
|
|
|
|
|
sub
|
|
et_addEvt($$$$)
|
|
{
|
|
my ($h, $name, $evt, $cnt) = @_;
|
|
return 0 if($evt =~ m/ CULHM (SND|RCV) /); # HM
|
|
return 0 if($evt =~ m/RAWMSG/); # HM
|
|
return 0 if($evt =~ m/^R-/); # HM register values
|
|
return 0 if($evt =~ m/ UNKNOWNCODE /);
|
|
return 0 if($evt =~ m/^\d+ global /); # update
|
|
return 0 if($evt =~ m/[<>]/); # HTML
|
|
return 0 if($evt =~ m/googlecom$/); # Kalender
|
|
return 0 if($evt =~ m/\.gif$/); # Proplanta
|
|
return 0 if(length($evt) > 80); # Safety
|
|
|
|
$evt =~ s/ *$//; # HM?
|
|
$evt =~ s/(Long|LongRelease) \d+_\d+/$1 .* /; # HM?
|
|
$evt =~ s/rgb: [0-9a-f]{6}/rgb: .*/; # Hue
|
|
$evt =~ s/: [0-9A-F]*$/: .*/; # PANSTAMP
|
|
$evt =~ s/\b-?\d*\.?\d+\b/.*/g; # Number to .*
|
|
$evt =~ s/\.\*.*\.\*/.*/g; # Multiple wildcards to one
|
|
$evt =~ s/set_\d+/set_.*/; # HM
|
|
$evt =~ s/\b\d+_next:\d+s\b/.*/g; # HM motionCount
|
|
$evt =~ s/^trigger: (.*_)\d+$/trigger: $1.*/; # HM
|
|
$evt =~ s/\.\* \(\d+K\)/.*/g; # HUE: Kelvin
|
|
$evt =~ s/ +/ /; #
|
|
$evt =~ s/HASH\(0x.*/.*/; # buggy event (Forum #36818)
|
|
$evt =~ s/[\n\r].*//s; # typical ECMD problem
|
|
|
|
$h->{$name}{_etCounter}++ if(!$h->{$name}{$evt});
|
|
$h->{$name}{$evt} += $cnt;
|
|
}
|
|
|
|
#####################################
|
|
sub
|
|
eventTypes_Define($$)
|
|
{
|
|
my ($hash, $def) = @_;
|
|
my @a = split("[ \t][ \t]*", $def);
|
|
|
|
return "wrong syntax: define <name> eventTypes filename" if(int(@a) != 3);
|
|
|
|
my $cnt = 0;
|
|
my @t = localtime;
|
|
my $f = ResolveDateWildcards($a[2], @t);
|
|
return "Only one eventTypes can be defined" if($modules{eventTypes}{ldata});
|
|
|
|
my ($err, @content) = FileRead($f);
|
|
my (%h1, %h2);
|
|
$hash->{ignoreList} = \%h2;
|
|
$modules{eventTypes}{ldata} = \%h1;
|
|
foreach my $l (@content) {
|
|
next if(!defined($l));
|
|
my @l = split(" ", $l, 3);
|
|
if(@l != 3) {
|
|
Log3 undef, 2, "eventTypes: $f: bogus line $l";
|
|
next;
|
|
}
|
|
next if(!$h1{$l[1]} && !goodDeviceName($l[1])); # Sanitizing: 117259
|
|
et_addEvt(\%h1, $l[1], $l[2], $l[0]);
|
|
}
|
|
|
|
Log3 undef, 2, "eventTypes: loaded ".int(@content)." lines from $f";
|
|
|
|
$hash->{STATE} = "active";
|
|
return undef;
|
|
}
|
|
|
|
#####################################
|
|
sub
|
|
eventTypes_Notify($$)
|
|
{
|
|
my ($me, $eventSrc) = @_;
|
|
my $ln = $me->{NAME};
|
|
return "" if($attr{$ln} && $attr{$ln}{disable});
|
|
|
|
my $events = deviceEvents($eventSrc, 1);
|
|
return if(!$events);
|
|
|
|
my $t = $eventSrc->{TYPE};
|
|
my $n = $eventSrc->{NAME};
|
|
return if(!defined($n) || !defined($t));
|
|
return if($me->{ignoreList}{$n});
|
|
|
|
my $h = $modules{eventTypes}{ldata};
|
|
return if($h->{$n} && $h->{$n}{_etCounter} && $h->{$n}{_etCounter} >= 200);
|
|
|
|
if($n eq "global") {
|
|
foreach my $oe (@{$events}) {
|
|
if($oe =~ m/^DELETED (.+)$/) {
|
|
delete $h->{$1};
|
|
}
|
|
if($oe =~ m/^RENAMED (.+) (.+)$/) {
|
|
$h->{$2} = $h->{$1};
|
|
delete $h->{$1};
|
|
}
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
my $ret = "";
|
|
foreach my $oe (@{$events}) {
|
|
next if(!defined($oe) || $oe =~ m/^\s*$/);
|
|
et_addEvt($h, $n, $oe, 1);
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
eventTypes_Attr(@)
|
|
{
|
|
my @a = @_;
|
|
my $do = 0;
|
|
|
|
if($a[0] eq "set" && $a[2] eq "ignoreList") {
|
|
my %h;
|
|
my $ldata = $modules{eventTypes}{ldata};
|
|
foreach my $i (split(',', $a[3])) {
|
|
$h{$i} = 1;
|
|
delete $ldata->{$i};
|
|
}
|
|
$defs{$a[1]}{ignoreList} = \%h;
|
|
}
|
|
|
|
if($a[0] eq "set" && $a[2] eq "disable") {
|
|
$do = (!defined($a[3]) || $a[3]) ? 1 : 2;
|
|
}
|
|
$do = 2 if($a[0] eq "del" && (!$a[2] || $a[2] eq "disable"));
|
|
return if(!$do);
|
|
|
|
$defs{$a[1]}{STATE} = ($do == 1 ? "disabled" : "active");
|
|
return undef;
|
|
}
|
|
|
|
###################################
|
|
sub
|
|
eventTypes_Undef()
|
|
{
|
|
delete $modules{eventTypes}{ldata};
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
eventTypes_Shutdown($$)
|
|
{
|
|
my ($hash, $name) = @_;
|
|
|
|
my @content;
|
|
my $fName = $hash->{DEF};
|
|
my $ldata = $modules{eventTypes}{ldata};
|
|
foreach my $t (sort keys %{$ldata}) {
|
|
foreach my $e (sort keys %{$ldata->{$t}}) {
|
|
next if($e eq "_etCounter");
|
|
push @content, "$ldata->{$t}{$e} $t $e";
|
|
}
|
|
}
|
|
FileWrite($fName, @content);
|
|
return undef;
|
|
}
|
|
|
|
###################################
|
|
sub
|
|
eventTypes_Set($@)
|
|
{
|
|
my ($hash, @a) = @_;
|
|
|
|
return $modules{eventTypes}{ldata} = undef
|
|
if($a[1] eq "clear");
|
|
return eventTypes_Shutdown($hash, $hash->{NAME})
|
|
if($a[1] eq "flush");
|
|
return "Unknown argument $a[1], choose one of clear:noArg flush:noArg";
|
|
}
|
|
|
|
###################################
|
|
sub
|
|
eventTypes_Get($@)
|
|
{
|
|
my ($hash, @a) = @_;
|
|
my $cmd = (defined($a[1]) ? $a[1] : "");
|
|
my $arg = $a[2];
|
|
|
|
return "Unknown argument $cmd, choose one of list listWithCounter"
|
|
if($cmd ne "list" && $cmd ne "listWithCounter");
|
|
my $out = "";
|
|
my $ldata = $modules{eventTypes}{ldata};
|
|
foreach my $t (sort keys %{$ldata}) {
|
|
next if($arg && $t ne $arg);
|
|
foreach my $e (sort keys %{$ldata->{$t}}) {
|
|
next if($e eq "_etCounter");
|
|
$out .=$cmd eq "listWithCounter" ? "$t $e $ldata->{$t}{$e}\n" : "$t $e\n";
|
|
}
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
1;
|
|
|
|
=pod
|
|
=item helper
|
|
=item summary collects FHEM Events to be used in frontends
|
|
=item summary_DE Sammelt FHEM Events fü die Frontends.
|
|
=begin html
|
|
|
|
<a name="eventTypes"></a>
|
|
<h3>eventTypes</h3>
|
|
<ul>
|
|
<br>
|
|
<a name="eventTypesdefine"></a>
|
|
<b>Define</b>
|
|
<ul>
|
|
<code>define <name> eventTypes <filename></code>
|
|
<br><br>
|
|
Collect event types for all devices. This service is used by frontends,
|
|
e.g. notify and FileLog, to assist you in selecting the correct events.
|
|
The filename is used to store the collected events before shutdown.<br>
|
|
More than one instance of eventTypes should not be necessary.
|
|
Examples:
|
|
<ul>
|
|
<code>define et eventTypes log/eventTypes.txt</code><br>
|
|
</ul>
|
|
<br>
|
|
</ul>
|
|
<br>
|
|
|
|
<a name="eventTypesset"></a>
|
|
<b>Set</b>
|
|
<ul>
|
|
<li>flush<br>
|
|
used to write all collected event types into datafile.
|
|
</li>
|
|
<br/>
|
|
<li>clear<br>
|
|
used to clear the internal table containing all collected event types.
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
|
|
<a name="eventTypesget"></a>
|
|
<b>Get</b>
|
|
<ul>
|
|
<li>list [devicename]<br>
|
|
listWithCounter [devicename]<br>
|
|
return the list of collected event types for all devices or for
|
|
devicename if specified.
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
|
|
<a name="eventTypesattr"></a>
|
|
<b>Attributes</b>
|
|
<ul>
|
|
<li><a href="#disable">disable</a></li><br>
|
|
<a name="ignoreList"></a>
|
|
<li>ignoreList<br>
|
|
Comma separated device names to ignore whe collecting the events.
|
|
E.g. ECMD-Devices are used to post RAW data as events.
|
|
</li><br>
|
|
</ul>
|
|
<br>
|
|
|
|
</ul>
|
|
|
|
=end html
|
|
=cut
|