mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-08 13:24:56 +00:00
unix line-end, editorial changes
git-svn-id: https://svn.fhem.de/fhem/trunk@4562 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
0c30ea9283
commit
ec22fe91fb
@ -410,10 +410,10 @@ sub HMLAN_Write($$$) {#########################################################
|
||||
if (length($msg)>22){
|
||||
my ($mtype,$src,$dst) = (substr($msg, 8, 2),
|
||||
substr($msg, 10, 6),
|
||||
substr($msg, 16, 6));
|
||||
substr($msg, 16, 6));
|
||||
|
||||
if ( $mtype eq "02" && $src eq $hash->{owner} && length($msg) == 24
|
||||
&& $hash->{assignIDs} =~ m/$dst/){
|
||||
&& $hash->{assignedIDs} =~ m/$dst/){
|
||||
# Acks are generally send by HMLAN autonomously
|
||||
# Special
|
||||
Log3 $hash, 5, "HMLAN: Skip ACK" if (!$debug);
|
||||
@ -440,8 +440,8 @@ sub HMLAN_Write($$$) {#########################################################
|
||||
}
|
||||
$hash->{helper}{$dst}{name} = CUL_HM_id2Name($dst);
|
||||
$lhash{$dst} = 1;
|
||||
$hash->{assignIDs}=join(',',keys %lhash);
|
||||
$hash->{assignIDsCnt}=scalar(keys %lhash);
|
||||
$hash->{assignedIDs}=join(',',keys %lhash);
|
||||
$hash->{assignedIDsCnt}=scalar(keys %lhash);
|
||||
}
|
||||
}
|
||||
my $tm = int(gettimeofday()*1000) % 0xffffffff;
|
||||
@ -651,7 +651,7 @@ sub HMLAN_Parse($$) {##########################################################
|
||||
$hash->{firmware} = sprintf("%d.%d", (hex($mFld[1])>>12)&0xf, hex($mFld[1]) & 0xffff);
|
||||
$hash->{owner} = $mFld[4];
|
||||
$hash->{uptime} = HMLAN_uptime($mFld[5],$hash);
|
||||
$hash->{assignIDsReport}=hex($mFld[6]);
|
||||
$hash->{assignedIDsReport}=hex($mFld[6]);
|
||||
$hash->{helper}{q}{keepAliveRec} = 1;
|
||||
$hash->{helper}{q}{keepAliveRpt} = 0;
|
||||
Log3 $hash, ($hash->{helper}{log}{sys}?0:5)
|
||||
|
@ -1,209 +1,209 @@
|
||||
################################################################
|
||||
# $Id: 98_apptime.pm $
|
||||
#
|
||||
################################################################
|
||||
|
||||
#####################################################
|
||||
#
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use vars qw(%defs); # FHEM device/button definitions
|
||||
use vars qw(%intAt);
|
||||
use vars qw($nextat);
|
||||
|
||||
sub apptime_Initialize($);
|
||||
|
||||
sub apptime_Initialize($){
|
||||
$cmds{"apptime"}{Fn} = "apptime_CommandDispTiming";
|
||||
$cmds{"apptime"}{Hlp} = "[clear|<field>] [top|all] [<filter>] application function calls and duration";
|
||||
}
|
||||
|
||||
sub HandleTimeout() {
|
||||
return undef if(!$nextat);
|
||||
|
||||
my $now = gettimeofday();
|
||||
return ($nextat-$now) if($now < $nextat);
|
||||
|
||||
$now += 0.01;# need to cover min delay at least
|
||||
$nextat = 0;
|
||||
#############
|
||||
# Check the internal list.
|
||||
foreach my $i (sort { $intAt{$a}{TRIGGERTIME} <=>
|
||||
$intAt{$b}{TRIGGERTIME} } keys %intAt) {
|
||||
my $tim = $intAt{$i}{TRIGGERTIME};
|
||||
my $fn = $intAt{$i}{FN};
|
||||
if(!defined($tim) || !defined($fn)) {
|
||||
delete($intAt{$i});
|
||||
next;
|
||||
} elsif($tim <= $now) {
|
||||
my $arg = $intAt{$i}{ARG};
|
||||
$arg = "" if (!$arg);
|
||||
|
||||
apptime_getTiming("global","tmr-".$fn.";".$arg,$fn,$arg);
|
||||
|
||||
delete($intAt{$i});
|
||||
} else {
|
||||
$nextat = $tim if(!$nextat || $nextat > $tim);
|
||||
}
|
||||
}
|
||||
|
||||
return undef if(!$nextat);
|
||||
$now = gettimeofday(); # possibly some tasks did timeout in the meantime
|
||||
# we will cover them
|
||||
return ($now+ 0.01 < $nextat) ? ($nextat-$now) : 0.01;
|
||||
}
|
||||
sub CallFn(@) {
|
||||
my $d = shift;
|
||||
my $n = shift;
|
||||
|
||||
if(!$d || !$defs{$d}) {
|
||||
$d = "<undefined>" if(!defined($d));
|
||||
Log 0, "Strange call for nonexistent $d: $n";
|
||||
return undef;
|
||||
}
|
||||
if(!$defs{$d}{TYPE}) {
|
||||
Log 0, "Strange call for typeless $d: $n";
|
||||
return undef;
|
||||
}
|
||||
my $fn = $modules{$defs{$d}{TYPE}}{$n};
|
||||
return "" if(!$fn);
|
||||
|
||||
my @ret = apptime_getTiming($d,$fn,$fn,@_);
|
||||
|
||||
if(wantarray){return @ret;}
|
||||
else {return $ret[0];}
|
||||
}
|
||||
|
||||
sub apptime_getTiming($$$@) {
|
||||
my ($e,$fnName,$fn,@arg) = @_;
|
||||
if (!$defs{$e}{helper} ||
|
||||
!$defs{$e}{helper}{bm} ||
|
||||
!$defs{$e}{helper}{bm}{$fnName} ){
|
||||
$defs{$e}{helper}{bm}{$fnName}{max}=0;
|
||||
$defs{$e}{helper}{bm}{$fnName}{mAr}="";
|
||||
$defs{$e}{helper}{bm}{$fnName}{cnt}=0;
|
||||
$defs{$e}{helper}{bm}{$fnName}{tot}=0;
|
||||
}
|
||||
my $h = $defs{$e}{helper}{bm}{$fnName};
|
||||
$h->{cnt}++;
|
||||
my $ts1 = gettimeofday();
|
||||
|
||||
no strict "refs";
|
||||
my @ret = &{$fn}(@arg);
|
||||
use strict "refs";
|
||||
|
||||
$ts1 = int((gettimeofday()-$ts1)*1000);
|
||||
if ($ts1 && $h->{max}<$ts1){
|
||||
$h->{max}=$ts1;
|
||||
$h->{mAr}=join ("; ",@arg);
|
||||
}
|
||||
;
|
||||
$h->{tot}+=$ts1;
|
||||
return @ret;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub apptime_CommandDispTiming($$@) {
|
||||
my ($cl,$param) = @_;
|
||||
my ($sFld,$top,$filter) = split" ",$param;
|
||||
$sFld = "max" if (!$sFld);
|
||||
$top = "top" if (!$top);
|
||||
my %fld = (name=>0,funktion=>1,max=>2,count=>3,total=>4,average=>5,clear=>99);
|
||||
return "$sFld undefined field, use one of ".join(",",keys %fld)
|
||||
if(!defined $fld{$sFld});
|
||||
my @bmArr;
|
||||
foreach my $d (sort keys %defs) {
|
||||
next if(!$defs{$d}{helper}||!$defs{$d}{helper}{bm});
|
||||
if ($sFld eq "clear"){
|
||||
delete $defs{$d}{helper}{bm};
|
||||
next;
|
||||
}
|
||||
foreach my $f (sort keys %{$defs{$d}{helper}{bm}}) {
|
||||
next if(!defined $defs{$d}{helper}{bm}{$f}{cnt});
|
||||
next if($filter && $d !~ m/$filter/ && $f !~ m/$filter/);
|
||||
my ($n,$t) = ($d,$f);
|
||||
($n,$t) = split(";",$f,2) if ($d eq "global");
|
||||
$t = "" if (!defined $t);
|
||||
my $h = $defs{$d}{helper}{bm}{$f};
|
||||
push @bmArr,[($n,$t
|
||||
,$h->{max}
|
||||
,$h->{cnt}
|
||||
,$h->{tot}
|
||||
,$h->{tot} /$h->{cnt}
|
||||
,$h->{mAr}
|
||||
)];
|
||||
}
|
||||
}
|
||||
my $field = $fld{$sFld};
|
||||
if ($field>1){@bmArr = sort { $b->[$field] <=> $a->[$field] } @bmArr;}
|
||||
else {@bmArr = sort { $b->[$field] cmp $a->[$field] } @bmArr;}
|
||||
my $ret = sprintf("\n %35s %20s %6s %6s %8s %8s %s",
|
||||
"name","function","max","count","total","average","param Max call");
|
||||
my $end = ($top && $top eq "top")?20:@bmArr-1;
|
||||
$end = @bmArr-1 if ($end>@bmArr-1);
|
||||
|
||||
$ret .= sprintf("\n %35s %20s %6d %6d %8d %8.2f %s",@{$bmArr[$_]})for (0..$end);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
1;
|
||||
=pod
|
||||
=begin html
|
||||
|
||||
<a name="apptime"></a>
|
||||
<h3>apptime</h3>
|
||||
<ul>
|
||||
<code>apptime</code>
|
||||
<br>
|
||||
<br>
|
||||
apptime provides information about application procedure execution time.
|
||||
It is meant to support finding long runner jobs causing latency as well as
|
||||
overall high cpu usage jobs<br>
|
||||
no information about FHEM kernal times and delays will be provided. <br>
|
||||
Once started apptime monitors tasks. User may reset counts during operation.
|
||||
apptime itself may add about 1% CPU load in average to FHEM.
|
||||
in order to remove apptime shutdown restart is necessary ist necessary.
|
||||
<br>
|
||||
<br>
|
||||
<b>Features:</b><br>
|
||||
<ul>
|
||||
<li><code>apptime</code><br>
|
||||
apptime is started with the its first call. It will monitor operation from that point in time<br>
|
||||
To unload apptime shutdeon restart is necessary<br> </li>
|
||||
<li><code>apptime clear</code><br>
|
||||
will reset all counts and start fom zero<br> </li>
|
||||
<li><code>apptime [count|funktion|average|clear|max|name|total] [all]</code><br>
|
||||
display a table sorted by the field selected<br>
|
||||
<b>all</b> will display the complete table while by default only the top lines are printed. <br></li>
|
||||
</ul>
|
||||
<br>
|
||||
<b>Columns:</b><br>
|
||||
<ul>
|
||||
<li><b>name</b><br>
|
||||
name of the entity executing the procedure<br>
|
||||
if it is a function called by InternalTimer the name starts with <b>tmr-</b>.
|
||||
by then it gives the name of the funktion to be called<br>
|
||||
</li>
|
||||
<li><b>function</b><br>
|
||||
procedure name which was executed<br>
|
||||
if it is an InternalTimer call it gives its calling parameter <br>
|
||||
</li>
|
||||
<li><b>max</b><br>
|
||||
longest duration measured for this procedure in ms <br> </li>
|
||||
<li><b>count</b><br>
|
||||
number of calls for this procedure<br> </li>
|
||||
<li><b>total</b><br>
|
||||
accumulated duration of this procedure over all calls monitored<br> </li>
|
||||
<li><b>average</b><br>
|
||||
average time a call of this procedure takes<br> </li>
|
||||
<li><b>param Max call</b><br>
|
||||
gives the parameter of the call with the max duration<br> </li>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
=cut
|
||||
################################################################
|
||||
# $Id: 98_apptime.pm $
|
||||
#
|
||||
################################################################
|
||||
|
||||
#####################################################
|
||||
#
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use vars qw(%defs); # FHEM device/button definitions
|
||||
use vars qw(%intAt);
|
||||
use vars qw($nextat);
|
||||
|
||||
sub apptime_Initialize($);
|
||||
|
||||
sub apptime_Initialize($){
|
||||
$cmds{"apptime"}{Fn} = "apptime_CommandDispTiming";
|
||||
$cmds{"apptime"}{Hlp} = "[clear|<field>] [top|all] [<filter>] application function calls and duration";
|
||||
}
|
||||
|
||||
sub HandleTimeout() {
|
||||
return undef if(!$nextat);
|
||||
|
||||
my $now = gettimeofday();
|
||||
return ($nextat-$now) if($now < $nextat);
|
||||
|
||||
$now += 0.01;# need to cover min delay at least
|
||||
$nextat = 0;
|
||||
#############
|
||||
# Check the internal list.
|
||||
foreach my $i (sort { $intAt{$a}{TRIGGERTIME} <=>
|
||||
$intAt{$b}{TRIGGERTIME} } keys %intAt) {
|
||||
my $tim = $intAt{$i}{TRIGGERTIME};
|
||||
my $fn = $intAt{$i}{FN};
|
||||
if(!defined($tim) || !defined($fn)) {
|
||||
delete($intAt{$i});
|
||||
next;
|
||||
} elsif($tim <= $now) {
|
||||
my $arg = $intAt{$i}{ARG};
|
||||
$arg = "" if (!$arg);
|
||||
|
||||
apptime_getTiming("global","tmr-".$fn.";".$arg,$fn,$arg);
|
||||
|
||||
delete($intAt{$i});
|
||||
} else {
|
||||
$nextat = $tim if(!$nextat || $nextat > $tim);
|
||||
}
|
||||
}
|
||||
|
||||
return undef if(!$nextat);
|
||||
$now = gettimeofday(); # possibly some tasks did timeout in the meantime
|
||||
# we will cover them
|
||||
return ($now+ 0.01 < $nextat) ? ($nextat-$now) : 0.01;
|
||||
}
|
||||
sub CallFn(@) {
|
||||
my $d = shift;
|
||||
my $n = shift;
|
||||
|
||||
if(!$d || !$defs{$d}) {
|
||||
$d = "<undefined>" if(!defined($d));
|
||||
Log 0, "Strange call for nonexistent $d: $n";
|
||||
return undef;
|
||||
}
|
||||
if(!$defs{$d}{TYPE}) {
|
||||
Log 0, "Strange call for typeless $d: $n";
|
||||
return undef;
|
||||
}
|
||||
my $fn = $modules{$defs{$d}{TYPE}}{$n};
|
||||
return "" if(!$fn);
|
||||
|
||||
my @ret = apptime_getTiming($d,$fn,$fn,@_);
|
||||
|
||||
if(wantarray){return @ret;}
|
||||
else {return $ret[0];}
|
||||
}
|
||||
|
||||
sub apptime_getTiming($$$@) {
|
||||
my ($e,$fnName,$fn,@arg) = @_;
|
||||
if (!$defs{$e}{helper} ||
|
||||
!$defs{$e}{helper}{bm} ||
|
||||
!$defs{$e}{helper}{bm}{$fnName} ){
|
||||
$defs{$e}{helper}{bm}{$fnName}{max}=0;
|
||||
$defs{$e}{helper}{bm}{$fnName}{mAr}="";
|
||||
$defs{$e}{helper}{bm}{$fnName}{cnt}=0;
|
||||
$defs{$e}{helper}{bm}{$fnName}{tot}=0;
|
||||
}
|
||||
my $h = $defs{$e}{helper}{bm}{$fnName};
|
||||
$h->{cnt}++;
|
||||
my $ts1 = gettimeofday();
|
||||
|
||||
no strict "refs";
|
||||
my @ret = &{$fn}(@arg);
|
||||
use strict "refs";
|
||||
|
||||
$ts1 = int((gettimeofday()-$ts1)*1000);
|
||||
if ($ts1 && $h->{max}<$ts1){
|
||||
$h->{max}=$ts1;
|
||||
$h->{mAr}=join ("; ",@arg);
|
||||
}
|
||||
;
|
||||
$h->{tot}+=$ts1;
|
||||
return @ret;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub apptime_CommandDispTiming($$@) {
|
||||
my ($cl,$param) = @_;
|
||||
my ($sFld,$top,$filter) = split" ",$param;
|
||||
$sFld = "max" if (!$sFld);
|
||||
$top = "top" if (!$top);
|
||||
my %fld = (name=>0,funktion=>1,max=>2,count=>3,total=>4,average=>5,clear=>99);
|
||||
return "$sFld undefined field, use one of ".join(",",keys %fld)
|
||||
if(!defined $fld{$sFld});
|
||||
my @bmArr;
|
||||
foreach my $d (sort keys %defs) {
|
||||
next if(!$defs{$d}{helper}||!$defs{$d}{helper}{bm});
|
||||
if ($sFld eq "clear"){
|
||||
delete $defs{$d}{helper}{bm};
|
||||
next;
|
||||
}
|
||||
foreach my $f (sort keys %{$defs{$d}{helper}{bm}}) {
|
||||
next if(!defined $defs{$d}{helper}{bm}{$f}{cnt});
|
||||
next if($filter && $d !~ m/$filter/ && $f !~ m/$filter/);
|
||||
my ($n,$t) = ($d,$f);
|
||||
($n,$t) = split(";",$f,2) if ($d eq "global");
|
||||
$t = "" if (!defined $t);
|
||||
my $h = $defs{$d}{helper}{bm}{$f};
|
||||
push @bmArr,[($n,$t
|
||||
,$h->{max}
|
||||
,$h->{cnt}
|
||||
,$h->{tot}
|
||||
,$h->{tot} /$h->{cnt}
|
||||
,$h->{mAr}
|
||||
)];
|
||||
}
|
||||
}
|
||||
my $field = $fld{$sFld};
|
||||
if ($field>1){@bmArr = sort { $b->[$field] <=> $a->[$field] } @bmArr;}
|
||||
else {@bmArr = sort { $b->[$field] cmp $a->[$field] } @bmArr;}
|
||||
my $ret = sprintf("\n %35s %20s %6s %6s %8s %8s %s",
|
||||
"name","function","max","count","total","average","param Max call");
|
||||
my $end = ($top && $top eq "top")?20:@bmArr-1;
|
||||
$end = @bmArr-1 if ($end>@bmArr-1);
|
||||
|
||||
$ret .= sprintf("\n %35s %20s %6d %6d %8d %8.2f %s",@{$bmArr[$_]})for (0..$end);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
1;
|
||||
=pod
|
||||
=begin html
|
||||
|
||||
<a name="apptime"></a>
|
||||
<h3>apptime</h3>
|
||||
<ul>
|
||||
<code>apptime</code>
|
||||
<br>
|
||||
<br>
|
||||
apptime provides information about application procedure execution time.
|
||||
It is designed to identify long runner jobs causing latency as well as
|
||||
overall high cpu usage jobs<br>
|
||||
No information about FHEM kernel times and delays will be provided. <br>
|
||||
Once started apptime monitors tasks. User may reset counter during operation.
|
||||
apptime adds about 1% CPU load in average to FHEM.
|
||||
in order to remove apptime shutdown restart is necessary.
|
||||
<br>
|
||||
<br>
|
||||
<b>Features:</b><br>
|
||||
<ul>
|
||||
<li><code>apptime</code><br>
|
||||
apptime is started with the its first call nad continously monitor operation.<br>
|
||||
To unload apptime shutdown restart is necessary<br> </li>
|
||||
<li><code>apptime clear</code><br>
|
||||
reset all counter and start fom Zero<br> </li>
|
||||
<li><code>apptime [count|funktion|average|clear|max|name|total] [all]</code><br>
|
||||
display a table sorted by the field selected<br>
|
||||
<b>all</b> will display the complete table while by default only the top lines are printed. <br></li>
|
||||
</ul>
|
||||
<br>
|
||||
<b>Columns:</b><br>
|
||||
<ul>
|
||||
<li><b>name</b><br>
|
||||
name of the entity executing the procedure<br>
|
||||
if it is a function called by InternalTimer the name starts with <b>tmr-</b>.
|
||||
by then it gives the name of the funktion to be called<br>
|
||||
</li>
|
||||
<li><b>function</b><br>
|
||||
procedure name which was executed<br>
|
||||
if it is an InternalTimer call it gives its calling parameter <br>
|
||||
</li>
|
||||
<li><b>max</b><br>
|
||||
longest duration measured for this procedure in ms <br> </li>
|
||||
<li><b>count</b><br>
|
||||
number of calls for this procedure<br> </li>
|
||||
<li><b>total</b><br>
|
||||
accumulated duration of this procedure over all calls monitored<br> </li>
|
||||
<li><b>average</b><br>
|
||||
average time a call of this procedure takes<br> </li>
|
||||
<li><b>param Max call</b><br>
|
||||
gives the parameter of the call with the max duration<br> </li>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
=cut
|
||||
|
Loading…
x
Reference in New Issue
Block a user