mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-13 05:06:35 +00:00
-feature: remove device from DeviceMonitor is attr device_timeout is set to 0 or removed
-feature: get function implemented, get <name> <criteria1>_<criteria2> criteria1 can be dead, alive or total criteria2 can be count, text or html git-svn-id: https://svn.fhem.de/fhem/trunk@2038 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
2b8eac8fd5
commit
12040bd695
@ -1,124 +1,266 @@
|
||||
# $Id: 98_DeviceMonitor.pm $
|
||||
#
|
||||
# Copyright (C) 2012 Dennis Gnoyke
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the same terms as Perl itself, either Perl version 5.8.7 or,
|
||||
# at your option, any later version of Perl 5 you may have available.
|
||||
#
|
||||
package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub DeviceMonitor_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
$hash->{DefFn} = "DeviceMonitor_Define";
|
||||
$hash->{NotifyFn} = "DeviceMonitor_Notify";
|
||||
$hash->{AttrList} = "disable:0,1";
|
||||
addToAttrList("device_timeout");
|
||||
}
|
||||
|
||||
sub DeviceMonitor_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
my $u = "wrong syntax: define <name> DeviceMonitor ";
|
||||
return $u if(int(@a) < 2);
|
||||
$hash->{CHANGED}[0] = "DEFINED";
|
||||
$hash->{STATE} = "DEFINED";
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub DeviceMonitor_Notify($$)
|
||||
{
|
||||
#*******************************************************************************
|
||||
# Purpose: Checks for timeout - Notify reacts on triggers fired from the Device
|
||||
# Author : Dennis Gnoyke
|
||||
# Date : 21.10.2012
|
||||
# Changes: 27.10.2012 GN Code optimized, Events reduced
|
||||
# Remarks: EXPERIMENTAL VERSION !!!!!!!
|
||||
#
|
||||
#**************************** Begin of Code *************************************
|
||||
my ($ownhash, $devhash) = @_;
|
||||
my $devName = $devhash->{NAME} ; #Name of the Device which has triggered this event
|
||||
my $ownName = $ownhash->{NAME} ; #Name of DeviceMonitor
|
||||
my $enabled = $ownhash->{ENABLED}; #DeviceMonitor enabled ?
|
||||
my $timeoutinterval = 0;
|
||||
my $devState = "unknown";
|
||||
|
||||
$timeoutinterval = AttrVal($devName, "device_timeout", "undef"); #Timeout configured ?
|
||||
return "" if ($timeoutinterval eq "undef");
|
||||
|
||||
$devhash->{HEALTH_MONITORED_BY} = $ownName;
|
||||
|
||||
if(AttrVal($devName, "disable", 0) > 0){$timeoutinterval = 0}; #Device Enabled ?
|
||||
if(AttrVal($ownName, "disable", 0) > 0) #DeviceMonitor Enabled ?
|
||||
{
|
||||
$timeoutinterval = 0;
|
||||
$ownhash->{STATE} = "DISABLED";
|
||||
}
|
||||
else
|
||||
{
|
||||
$ownhash->{STATE} = "ENABLED";
|
||||
}
|
||||
|
||||
# Get current HealthState
|
||||
if (!defined($devhash->{HEALTH_STATE}))
|
||||
{
|
||||
$devState = "unknown";
|
||||
}
|
||||
else
|
||||
{
|
||||
$devState = $devhash->{HEALTH_STATE};
|
||||
}
|
||||
|
||||
if ($timeoutinterval < 1) #device_timeout set to 0
|
||||
{
|
||||
if ($devState ne "unknown"){DoTrigger($devName,"health_state: unknown")};
|
||||
$devhash->{HEALTH_STATE} = "unknown";
|
||||
$devhash->{HEALTH_TIME} = TimeNow();
|
||||
$ownhash->{READINGS}{$devName}{VAL} = "unknown";
|
||||
$ownhash->{READINGS}{$devName}{TIME} = TimeNow();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($devState ne "alive"){DoTrigger($devName,"health_state: alive")};
|
||||
RemoveInternalTimer($devhash);
|
||||
$devhash->{HEALTH_STATE} = "alive";
|
||||
$devhash->{HEALTH_TIME} = TimeNow();
|
||||
$ownhash->{READINGS}{$devName}{VAL} = "alive";
|
||||
$ownhash->{READINGS}{$devName}{TIME} = TimeNow();
|
||||
InternalTimer(gettimeofday()+($timeoutinterval*60), "DeviceMonitor_Timer", $devhash, 0);
|
||||
}
|
||||
return undef;
|
||||
#**************************** End of Code *************************************
|
||||
}
|
||||
|
||||
sub DeviceMonitor_Timer($)
|
||||
{
|
||||
#*******************************************************************************
|
||||
# Purpose: Checks for timeout - Will be called if timeout occured
|
||||
# Author : Dennis Gnoyke
|
||||
# Date : 21.10.2012
|
||||
# Changes: 22.10.2012 GN Typo Death -> Dead
|
||||
# Remarks: EXPERIMENTAL VERSION !!!!!!!
|
||||
#
|
||||
#**************************** Begin of Code *************************************
|
||||
#set the HEALTH_STATE to "dead" if not already set
|
||||
my ($devhash) = @_;
|
||||
my $ownName = $devhash->{HEALTH_MONITORED_BY};
|
||||
my $devName = $devhash->{NAME};
|
||||
|
||||
DoTrigger($devName,"health_state: dead");
|
||||
$devhash->{HEALTH_STATE} = "dead";
|
||||
$devhash->{HEALTH_TIME} = TimeNow();
|
||||
$defs{$ownName}{READINGS}{$devName}{TIME} = TimeNow();
|
||||
$defs{$ownName}{READINGS}{$devName}{VAL} = "dead";
|
||||
#**************************** End of Code *****************************************
|
||||
}
|
||||
# $Id: 98_DeviceMonitor.pm $
|
||||
#
|
||||
# Copyright (C) 2012 Dennis Gnoyke
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the same terms as Perl itself, either Perl version 5.8.7 or,
|
||||
# at your option, any later version of Perl 5 you may have available.
|
||||
#
|
||||
package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub DeviceMonitor_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
$hash->{DefFn} = "DeviceMonitor_Define";
|
||||
$hash->{UndefFn} = "DeviceMonitor_Undef";
|
||||
$hash->{NotifyFn} = "DeviceMonitor_Notify";
|
||||
$hash->{GetFn} = "DeviceMonitor_Get";
|
||||
$hash->{AttrList} = "disable:0,1";
|
||||
addToAttrList("device_timeout");
|
||||
}
|
||||
|
||||
sub DeviceMonitor_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
my $u = "wrong syntax: define <name> DeviceMonitor ";
|
||||
return $u if(int(@a) < 2);
|
||||
$hash->{CHANGED}[0] = "DEFINED";
|
||||
$hash->{STATE} = "DEFINED";
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub
|
||||
DeviceMonitor_Undef($$)
|
||||
{
|
||||
my ($hash, $arg) = @_;
|
||||
|
||||
return DeviceMonitor_Remove($hash,"all");
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
sub DeviceMonitor_Get($@)
|
||||
{
|
||||
#*******************************************************************************
|
||||
# Purpose: Get some results
|
||||
# Author : Dennis Gnoyke
|
||||
# Date : 27.10.2012
|
||||
# Changes:
|
||||
# Remarks:
|
||||
#**************************** Begin of Code *************************************
|
||||
my ($hash, @a) = @_;
|
||||
return "argument is missing" if(int(@a) != 2);
|
||||
|
||||
my ($criteria, $output) = split ("_",lc($a[1]));
|
||||
return DeviceMonitor_GetResult($a[0],$criteria,$output);
|
||||
#**************************** End of Code *****************************************
|
||||
}
|
||||
|
||||
sub DeviceMonitor_Notify($$)
|
||||
{
|
||||
#*******************************************************************************
|
||||
# Purpose: Checks for timeout - Notify reacts on triggers fired from the Device
|
||||
# Author : Dennis Gnoyke
|
||||
# Date : 21.10.2012
|
||||
# Changes: 27.10.2012 GN Code optimized, Events reduced
|
||||
# Remarks: EXPERIMENTAL VERSION !!!!!!!
|
||||
#
|
||||
#**************************** Begin of Code *************************************
|
||||
my ($ownhash, $devhash) = @_;
|
||||
my $devName = $devhash->{NAME} ; #Name of the Device which has triggered this event
|
||||
my $ownName = $ownhash->{NAME} ; #Name of DeviceMonitor
|
||||
my $enabled = $ownhash->{ENABLED}; #DeviceMonitor enabled ?
|
||||
my $timeoutinterval = 0;
|
||||
my $devState = "unknown";
|
||||
|
||||
$timeoutinterval = AttrVal($devName, "device_timeout", 0); #Timeout configured ?
|
||||
return "" if ($timeoutinterval < 1 && !defined($defs{$devName}{HEALTH_MONITORED_BY})); #Leave NTFY if device is not configured for DeviceMonitor
|
||||
|
||||
if(AttrVal($devName, "disable", 0) > 0){$timeoutinterval = 0}; #Device Enabled ?
|
||||
if(AttrVal($ownName, "disable", 0) > 0) #DeviceMonitor Enabled ?
|
||||
{
|
||||
$timeoutinterval = 0;
|
||||
$ownhash->{STATE} = "DISABLED";
|
||||
}
|
||||
else
|
||||
{
|
||||
$ownhash->{STATE} = "ENABLED";
|
||||
}
|
||||
|
||||
Log 4, "'$devName' is now monitored by '$ownName'" if(!defined($defs{$devName}{HEALTH_MONITORED_BY}));
|
||||
$devhash->{HEALTH_MONITORED_BY} = $ownName;
|
||||
# Get current HealthState
|
||||
if (!defined($devhash->{HEALTH_STATE})){$devState = "unknown"}else{$devState = $devhash->{HEALTH_STATE}}
|
||||
|
||||
if ($timeoutinterval < 1) #device_timeout set to 0, remove it from monitor
|
||||
{
|
||||
DeviceMonitor_Remove($ownName,$devName);
|
||||
RemoveInternalTimer($devhash);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($devState ne "alive"){DoTrigger($devName,"health_state: alive")};
|
||||
RemoveInternalTimer($devhash);
|
||||
$devhash->{HEALTH_STATE} = "alive";
|
||||
$devhash->{HEALTH_TIME} = TimeNow();
|
||||
$ownhash->{READINGS}{$devName}{VAL} = "alive";
|
||||
$ownhash->{READINGS}{$devName}{TIME} = TimeNow();
|
||||
InternalTimer(gettimeofday()+($timeoutinterval*60), "DeviceMonitor_Timer", $devhash, 0);
|
||||
}
|
||||
return undef;
|
||||
#**************************** End of Code *************************************
|
||||
}
|
||||
|
||||
sub DeviceMonitor_Timer($)
|
||||
{
|
||||
#*******************************************************************************
|
||||
# Purpose: Checks for timeout - Will be called if timeout occured
|
||||
# Author : Dennis Gnoyke
|
||||
# Date : 21.10.2012
|
||||
# Changes: 22.10.2012 GN Typo Death -> Dead
|
||||
# Remarks:
|
||||
#
|
||||
#**************************** Begin of Code *************************************
|
||||
#set the HEALTH_STATE to "dead" if not already set
|
||||
my ($devhash) = @_;
|
||||
my $ownName = $devhash->{HEALTH_MONITORED_BY};
|
||||
my $devName = $devhash->{NAME};
|
||||
|
||||
if(AttrVal($devName, "device_timeout", 0) < 1) #device_timeout set to 0, remove it from monitor
|
||||
{
|
||||
DeviceMonitor_Remove($ownName,$devName);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoTrigger($devName,"health_state: dead");
|
||||
$devhash->{HEALTH_STATE} = "dead";
|
||||
$devhash->{HEALTH_TIME} = TimeNow();
|
||||
$defs{$ownName}{READINGS}{$devName}{TIME} = TimeNow();
|
||||
$defs{$ownName}{READINGS}{$devName}{VAL} = "dead";
|
||||
}
|
||||
RemoveInternalTimer($devhash);
|
||||
#**************************** End of Code *****************************************
|
||||
}
|
||||
|
||||
sub DeviceMonitor_GetResult($$$)
|
||||
{
|
||||
#*******************************************************************************
|
||||
# Purpose: Get results from DeviceMonitor readings
|
||||
# Author : Dennis Gnoyke
|
||||
# Date : 27.10.2012
|
||||
# Changes:
|
||||
# Remarks: $_[0] = DeviceMonitor
|
||||
# $_[1] = Criteria dead|alive|total
|
||||
# $_[2] = Output as count|text|html
|
||||
#**************************** Begin of Code *************************************
|
||||
my $hash = $defs{$_[0]}{READINGS};
|
||||
my $cnt = 0; #counter
|
||||
my @result ; #result array
|
||||
$result[0] ="null"; #default
|
||||
my $tmp = ""; #temp var
|
||||
|
||||
foreach my $readings_name (sort keys %{$hash}) #Loop through Readings
|
||||
{
|
||||
my $val = $hash->{$readings_name};
|
||||
if(ref($val))
|
||||
{
|
||||
my $readings_value = $val->{VAL};
|
||||
my $readings_time = $val->{TIME};
|
||||
if ($readings_value eq $_[1]) #value like dead or alive
|
||||
{
|
||||
$result["$cnt"] = $readings_name.','."has health_state '$readings_value' reported at $readings_time";
|
||||
$cnt = $cnt + 1
|
||||
}
|
||||
elsif($_[1] eq "total")
|
||||
{
|
||||
$result["$cnt"] = $readings_name.','."has health_state '$readings_value' reported at $readings_time";
|
||||
$cnt = $cnt + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($result[0] eq "null")
|
||||
{
|
||||
return 0 if($_[2] eq "count");
|
||||
return "$_[0]: There was no match for your criteria '$_[1]'" if($_[2] eq "text");
|
||||
return "$_[0]: There was no match for your criteria '$_[1]'" if($_[2] eq "html");
|
||||
return "$_[0]: Unknown argument $_[2] , syntax is <criteria>_<output> criteria=dead,alive,total output=count,text,html";
|
||||
}
|
||||
else
|
||||
{
|
||||
if($_[2] eq "count"){return $cnt}
|
||||
elsif($_[2] eq "text")
|
||||
{
|
||||
foreach (@result)
|
||||
{
|
||||
my ($device, $value) = split (",",$_);
|
||||
$tmp .= "Device $device $value\n";
|
||||
}
|
||||
return $tmp;
|
||||
}
|
||||
elsif($_[2] eq "html")
|
||||
{
|
||||
$tmp = "<table>\n";
|
||||
foreach (@result)
|
||||
{
|
||||
my ($device, $value) = split (",",$_);
|
||||
$tmp .= "<tr><td>Device <a href='/fhem?detail=$device'>$device</a> $value</td></tr>\n";
|
||||
};
|
||||
$tmp .= "</table></div>";
|
||||
return $tmp;
|
||||
}
|
||||
else{return "$_[0]: Unknown argument $_[2] , syntax is <criteria>_<output> criteria=dead,alive,total output=count,text,html"}
|
||||
}
|
||||
#**************************** End of Code *****************************************
|
||||
}
|
||||
|
||||
|
||||
sub DeviceMonitor_Remove($$)
|
||||
{
|
||||
#*******************************************************************************
|
||||
# Purpose: Resets DeviceMonitor readings
|
||||
# Author : Dennis Gnoyke
|
||||
# Date : 28.10.2012
|
||||
# Changes:
|
||||
# Remarks: $_[0] = DeviceMonitor
|
||||
# $_[1] = Criteria devicename|all
|
||||
#
|
||||
#**************************** Begin of Code *************************************
|
||||
my $hash = $defs{$_[0]}{READINGS};
|
||||
|
||||
if(defined($hash->{$_[1]})) #remove single device from monitor
|
||||
{
|
||||
delete $hash->{$_[1]};
|
||||
if(defined($defs{$_[1]}{HEALTH_MONITORED_BY})){delete $defs{$_[1]}{HEALTH_MONITORED_BY}};
|
||||
if(defined($defs{$_[1]}{HEALTH_STATE})){delete $defs{$_[1]}{HEALTH_STATE}};
|
||||
if(defined($defs{$_[1]}{HEALTH_TIME})){delete $defs{$_[1]}{HEALTH_TIME}};
|
||||
RemoveInternalTimer($defs{$_[1]});
|
||||
Log 4, "'$_[1]' is no longer monitored by '$_[0]'";
|
||||
}
|
||||
elsif(uc($_[1]) eq "ALL") #remove all devices from monitor
|
||||
{
|
||||
foreach my $readings_name (sort keys %{$hash}) #Loop through Readings
|
||||
{
|
||||
delete $hash->{$readings_name};
|
||||
if(defined($defs{$readings_name}{HEALTH_MONITORED_BY})){delete $defs{$readings_name}{HEALTH_MONITORED_BY}};
|
||||
if(defined($defs{$readings_name}{HEALTH_STATE})){delete $defs{$readings_name}{HEALTH_STATE}};
|
||||
if(defined($defs{$readings_name}{HEALTH_TIME})){delete $defs{$readings_name}{HEALTH_TIME}};
|
||||
RemoveInternalTimer($defs{$readings_name});
|
||||
}
|
||||
Log 4, "all devices removed from '$_[0]', please note that devices will appear again if their device_timeout attr is still set and '$_[0]' is defined and enabled!";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "$_[0]: Can`t remove $_[1] check spelling and upper/lower cases";
|
||||
}
|
||||
|
||||
#**************************** End of Code *****************************************
|
||||
}
|
||||
|
||||
1;
|
Loading…
x
Reference in New Issue
Block a user