mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-01 20:20:10 +00:00
Watchdog added + small changes
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@221 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
bdf77c3db1
commit
f6bbddb4fe
3
CHANGED
3
CHANGED
@ -417,3 +417,6 @@
|
||||
- feature: autoloading FHEM modules
|
||||
- bugfix: STATE/$value is carrying again the correct value
|
||||
- feature: enhancing the Makefile and the documentation
|
||||
- feature: 90_at is using now InternalTimer, subsecond precision added
|
||||
- feature: HMS100-FIT added (01.01.08 by Peter and 22.01.08 by Juergen)
|
||||
- feature: 91_watchdog added to handle the HMS100-FIT
|
||||
|
@ -3,6 +3,7 @@ package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
|
||||
#####################################
|
||||
sub
|
||||
@ -11,7 +12,6 @@ at_Initialize($)
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{DefFn} = "at_Define";
|
||||
$hash->{TimeFn} = "at_Exec";
|
||||
$hash->{AttrFn} = "at_Attr";
|
||||
$hash->{AttrList} = "disable:0,1 skip_next:0,1";
|
||||
}
|
||||
@ -42,7 +42,7 @@ at_Define($$)
|
||||
$rep = "" if(!defined($rep));
|
||||
$cnt = "" if(!defined($cnt));
|
||||
|
||||
my $ot = time;
|
||||
my $ot = gettimeofday();
|
||||
my @lt = localtime($ot);
|
||||
my $nt = $ot;
|
||||
|
||||
@ -65,7 +65,7 @@ at_Define($$)
|
||||
}
|
||||
$hash->{NTM} = $ntm if($rel eq "+" || $fn);
|
||||
$hash->{TRIGGERTIME} = $nt;
|
||||
$nextat = $nt if(!$nextat || $nextat > $nt);
|
||||
InternalTimer($nt, "at_Exec", $name, 0);
|
||||
|
||||
$hash->{STATE} = "Next: " . FmtTime($nt);
|
||||
|
||||
|
108
FHEM/91_watchdog.pm
Executable file
108
FHEM/91_watchdog.pm
Executable file
@ -0,0 +1,108 @@
|
||||
##############################################
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
|
||||
#####################################
|
||||
sub
|
||||
watchdog_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{DefFn} = "watchdog_Define";
|
||||
$hash->{NotifyFn} = "watchdog_Notify";
|
||||
$hash->{AttrList} = "disable:0,1";
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
# defined watchme watchdog reg1 timeout reg2 command
|
||||
sub
|
||||
watchdog_Define($$)
|
||||
{
|
||||
my ($ntfy, $def) = @_;
|
||||
my ($name, $type, $re1, $to, $re2, $command) = split("[ \t]+", $def, 6);
|
||||
|
||||
return "Usage: define <name> watchdog <re1> <timeout> <re2> <command>"
|
||||
if(!$command);
|
||||
|
||||
# Checking for misleading regexps
|
||||
eval { "Hallo" =~ m/^$re1$/ };
|
||||
return "Bad regexp 1: $@" if($@);
|
||||
$re2 = $re1 if($re2 eq "SAME");
|
||||
eval { "Hallo" =~ m/^$re2$/ };
|
||||
return "Bad regexp 2: $@" if($@);
|
||||
|
||||
return "Wrong timespec, must be HH:MM[:SS]"
|
||||
if($to !~ m/^(\d\d):(\d\d)(:\d\d)?$/);
|
||||
$to = $1*3600+$2*60+($3 ? substr($3,1) : 0);
|
||||
|
||||
$ntfy->{RE1} = $re1;
|
||||
$ntfy->{RE2} = $re2;
|
||||
$ntfy->{TO} = $to;
|
||||
$ntfy->{CMD} = $command;
|
||||
|
||||
|
||||
$ntfy->{STATE} = ($re1 eq ".") ? "active" : "defined";
|
||||
watchdog_Activate($ntfy) if($ntfy->{STATE} eq "active");
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
watchdog_Notify($$)
|
||||
{
|
||||
my ($ntfy, $dev) = @_;
|
||||
|
||||
my $ln = $ntfy->{NAME};
|
||||
return "" if($attr{$ln} && $attr{$ln}{disable});
|
||||
|
||||
my $n = $dev->{NAME};
|
||||
my $re1 = $ntfy->{RE1};
|
||||
my $re2 = $ntfy->{RE2};
|
||||
my $max = int(@{$dev->{CHANGED}});
|
||||
|
||||
for (my $i = 0; $i < $max; $i++) {
|
||||
my $s = $dev->{CHANGED}[$i];
|
||||
$s = "" if(!defined($s));
|
||||
|
||||
if($ntfy->{STATE} =~ m/Next:/) {
|
||||
if($n =~ m/^$re2$/ || "$n:$s" =~ m/^$re2$/) {
|
||||
RemoveInternalTimer($ntfy);
|
||||
if($re1 eq $re2) {
|
||||
watchdog_Activate($ntfy);
|
||||
} else {
|
||||
$ntfy->{STATE} = "defined";
|
||||
}
|
||||
}
|
||||
} elsif($n =~ m/^$re1$/ || "$n:$s" =~ m/^$re1$/) {
|
||||
watchdog_Activate($ntfy);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
sub
|
||||
watchdog_Trigger($)
|
||||
{
|
||||
my ($ntfy) = @_;
|
||||
Log(3, "Watchdog $ntfy->{NAME} triggered");
|
||||
my $exec = SemicolonEscape($ntfy->{CMD});;
|
||||
AnalyzeCommandChain(undef, $exec);
|
||||
$ntfy->{STATE} = "triggered";
|
||||
}
|
||||
|
||||
sub
|
||||
watchdog_Activate($)
|
||||
{
|
||||
my ($ntfy) = @_;
|
||||
my $nt = gettimeofday() + $ntfy->{TO};
|
||||
$ntfy->{STATE} = "Next: " . FmtTime($nt);
|
||||
InternalTimer($nt, "watchdog_Trigger", $ntfy, 0)
|
||||
}
|
||||
|
||||
|
||||
1;
|
@ -283,7 +283,7 @@ make editing of multiline commands transparent.<br><br>
|
||||
|
||||
<a name="disable"></a>
|
||||
<li>disable<br>
|
||||
Can be applied to at/notify/FileLog devices.<br>
|
||||
Can be applied to at/watchdog/notify/FileLog devices.<br>
|
||||
Disables the corresponding at/notify or FileLog device. Note:
|
||||
If applied to an <a href="#at">at</a>, the command will not be executed,
|
||||
but the next time will be computed.</li><br>
|
||||
@ -424,7 +424,7 @@ fs20sv
|
||||
fs20sv
|
||||
fs20usr</pre></li>
|
||||
|
||||
<li>HMS: hms100-t hms100-tf hms100-wd hms100-mg hms100-tfk rm100-2</li>
|
||||
<li>HMS: hms100-t hms100-tf hms100-wd hms100-mg hms100-co hms100-tfk hms100-fit rm100-2</li>
|
||||
<li>KS300: ks300</li>
|
||||
<li>WS300: ws300pc</li>
|
||||
<li>EM1010: em1010pc</li>
|
||||
@ -701,24 +701,30 @@ fs20usr</pre></li>
|
||||
circumstances, the authors are not liable for any damage occuring as a
|
||||
result of incomplete or buggy code</li>
|
||||
|
||||
<li>Currently supported devices are the HMS100T, HMS100TF, HMS100WD and
|
||||
the RM100-2.</li>
|
||||
<li>Currently supported devices are the HMS100-T HMS100-TF HMS100-WD
|
||||
HMS100-MG HMS100-TFK HMS100-CO HMS100-FIT RM100-2 </li>
|
||||
|
||||
<li>The housecode of the HMS devices may change if the battery is renewed.
|
||||
In order to make life easier, you can define a "wildcard" device for each
|
||||
type of HMS device. First the real device-id will be checked, then the
|
||||
wildcard device id. The wildcards are:
|
||||
<ul>
|
||||
<li>1000 for the HMS100TF</li>
|
||||
<li>1001 for the HMS100T</li>
|
||||
<li>1002 for the HMS100WD</li>
|
||||
<li>1000 for the HMS100-TF</li>
|
||||
<li>1001 for the HMS100-T</li>
|
||||
<li>1002 for the HMS100-WD</li>
|
||||
<li>1003 for the RM100-2</li>
|
||||
<li>1006 for the HMS100MG</li>
|
||||
<li>1004 for the HMS100-TFK/li>
|
||||
<li>1006 for the HMS100-MG</li>
|
||||
<li>1008 for the HMS100-CO</li>
|
||||
<li>100e for the HMS100-FIT</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Some battery low notifications are not yet implemented (RM100, HMS100WD).</li>
|
||||
<li>Please test your installation before relying on the functionality.</li>
|
||||
<li>Some battery low notifications are not yet implemented (RM100,
|
||||
HMS100WD).</li>
|
||||
<li>Please test your installation before relying on the
|
||||
functionality.</li>
|
||||
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
@ -1181,6 +1187,43 @@ fs20usr</pre></li>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="watchdog"></a>
|
||||
<h4>Type watchdog</h4>
|
||||
<ul>
|
||||
<code>define <name> watchdog <regexp1> <timespec> <regexp2> <command></code><br>
|
||||
<br>
|
||||
Start an arbitrary fhem.pl command if after <timespec> receiving an
|
||||
event matching <regexp1> no event matching <regexp2> is
|
||||
received.<br>
|
||||
The syntax for <regexp1> and <regexp2> is the same as the
|
||||
regexp for <a href="#notify">notify</a>.<br>
|
||||
<timespec> is HH:MM[:SS]<br>
|
||||
<command> is a usual fhem command like used int the <a
|
||||
href="#at">at</a> or <a href="#notify">notify</a>
|
||||
<br><br>
|
||||
|
||||
Examples:
|
||||
<pre>
|
||||
# "Reset" the FHT80 if we do not receive any message for 15 Minutes
|
||||
define w watchdog FHT80 00:15:00 SAME set FHT80 refreshvalues
|
||||
# Shout if the HMS100-FIT is not alive
|
||||
define w watchdog HMS100-FIT 01:00:00 SAME "alarm-fit.sh"
|
||||
</pre>
|
||||
|
||||
Notes:<br>
|
||||
<ul>
|
||||
<li>if <regexp1> is . (dot), then activate the watchdog at
|
||||
definition time. Else it will be activated when the first matching event
|
||||
is received.</li>
|
||||
|
||||
<li>if <regexp2> is SAME, then it will be the same as the first
|
||||
regexp, and it will be reactivated, when it is received. This is probably
|
||||
the normal operation.</li>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<a name="notify"></a>
|
||||
<h4>Type notify</h4>
|
||||
<ul>
|
||||
|
@ -44,9 +44,16 @@ hex code needed by fhem.pl?</a><br><br>
|
||||
<a href="#faq11">11. I'd like to use this sunrise/sunset stuff, can you help
|
||||
me?</a><br><br>
|
||||
|
||||
<a href="#faq12">12. I'd like to switch on the ventilator if the FHT tells me its too hot. How to tell fhem to do that?</a><br><br>
|
||||
<a href="#faq12">12. I'd like to switch on the ventilator if the FHT tells me
|
||||
its too hot. How to tell fhem to do that?</a><br><br>
|
||||
|
||||
<a href="#faq13">13. I'd like to see directly in the Web frontend if a window
|
||||
is open. How to do that?</a><br><br>
|
||||
|
||||
<a href="#faq14">14. In the summer I get a lot of "actuator:lime-protection"
|
||||
messages from my FHT80b. How to switch back to the actuator:0% messages?</a>
|
||||
<br><br>
|
||||
|
||||
<a href="#faq12">13. I'd like to see directly in the Web frontend if a window is open. How to do that?</a><br><br>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
@ -285,5 +292,32 @@ How to do that? (by fwolff)</b>
|
||||
</pre>
|
||||
</ul>
|
||||
|
||||
<a name="faq14"></a>
|
||||
<b>14. In the summer I get a lot of "actuator:lime-protection
|
||||
messages from my FHT80b. How to switch back to the actuator:0% messages?
|
||||
</b>
|
||||
<ul>
|
||||
|
||||
(Thanks for Martin Fischer for researching)<br>
|
||||
The problem happens if at the weekly lime-protection time (usually saturday
|
||||
at 11:00 AM) the desired temperature is lower than the measured temperature.
|
||||
I think this is an FHT80b firmware bug, a workaround is to set the desired
|
||||
temperature for a short time higher than the measured temperature.
|
||||
You can automate it with the following notify:
|
||||
<pre>
|
||||
define lime_reset notify .*lime-protection {\
|
||||
$d = $defs{@}{READINGS}{"desired-temp"}{VAL};;\
|
||||
$m = $defs{@}{READINGS}{"measured-temp"}{VAL};;\
|
||||
if($m > $d) {\
|
||||
fhem("set @ desired-temp 29");;\
|
||||
fhem("set @ desired-temp $d");;\
|
||||
}\
|
||||
}
|
||||
</pre>
|
||||
|
||||
</ul>
|
||||
|
||||
<a name="faq14">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -38,7 +38,7 @@ Currently implemented features:<br>
|
||||
The FHT8b seems to work too. <b>Note:</b> the FHT8 wont work.<br>
|
||||
Internal software buffer to prevent lost commands.<br>
|
||||
</li>
|
||||
<li>reading HMS data (HMS100-T,-TF,-WD,-MG,-TFK and RM100-2)</li>
|
||||
<li>reading HMS data (HMS100-T,-TF,-WD,-MG,-TFK,-CO,-FIT and RM100-2)</li>
|
||||
<li>reading KS300 data</li>
|
||||
</ul>
|
||||
<b>Note:</b>The FHZ1350 WLAN is probably not working due to a prorietary
|
||||
@ -55,6 +55,7 @@ Currently implemented features:<br>
|
||||
<li>notifying external programs or internal modules when receiving certain
|
||||
events</li>
|
||||
<li>timed commands (e.g. switching a lamp on from sunset till midnight)</li>
|
||||
<li>watchdog (e.g. trigger if the HMS100-FIT is inactive for HH:MM:SS)</li>
|
||||
<li>modular architecture, easy to add your special device</li>
|
||||
<li>different web frontends, choose your favorite</li>
|
||||
<br>
|
||||
|
@ -32,3 +32,21 @@ define wz_refresh at *04:00:00 set wz report1 255 report2 255
|
||||
|
||||
# alias for the above
|
||||
define wz_refresh at *04:00:00 set wz refreshvalues
|
||||
|
||||
|
||||
###################
|
||||
# If at the weekly lime-protection time (usually saturday at 11:00 AM) the
|
||||
# desired temperature is lower than the measured temperature, then you'll get
|
||||
# instead of "actuator:0%" the "actuator:lime-protection" messsages every 2.5
|
||||
# minutes. I think this is an FHT80b firmware bug, a workaround is to set the
|
||||
# desired temperature for a short time higher than the measured temperature.
|
||||
# You can automate it (for all FHT's) with the following notify:
|
||||
|
||||
define lime_reset notify .*lime-protection {\
|
||||
my $d = $defs{@}{READINGS}{"desired-temp"}{VAL};;\
|
||||
my $m = $defs{@}{READINGS}{"measured-temp"}{VAL};;\
|
||||
if($m > $d) {\
|
||||
fhem("set @ desired-temp 29");;\
|
||||
fhem("set @ desired-temp $d");;\
|
||||
}\
|
||||
}
|
||||
|
27
fhem.pl
27
fhem.pl
@ -58,6 +58,7 @@ sub Log($$);
|
||||
sub OpenLogfile($);
|
||||
sub PrintHash($$);
|
||||
sub ResolveDateWildcards($@);
|
||||
sub RemoveInternalTimer($);
|
||||
sub SemicolonEscape($);
|
||||
sub SignalHandling();
|
||||
sub TimeNow();
|
||||
@ -103,7 +104,6 @@ sub CommandTrigger($$);
|
||||
# SetFn - set/activate this device
|
||||
# GetFn - get some data from this device
|
||||
# StateFn - set local info for this device, do not activate anything
|
||||
# TimeFn - if the TRIGGERTIME of a device is reached, call this function
|
||||
# NotifyFn - call this if some device changed its properties
|
||||
# ReadyFn - check for available data, if no FD
|
||||
# ReadFn - Reading from a Device (see FHZ/WS300)
|
||||
@ -125,7 +125,6 @@ use vars qw(%attr); # Attributes
|
||||
|
||||
use vars qw(%value); # Current values, see commandref.html
|
||||
use vars qw(%oldvalue); # Old values, see commandref.html
|
||||
use vars qw($nextat); # used by the at module
|
||||
use vars qw($init_done); #
|
||||
use vars qw($internal_data); #
|
||||
|
||||
@ -140,10 +139,11 @@ my $global_cl; # To use from perl snippets
|
||||
my $devcount = 0; # To sort the devices
|
||||
my %defaultattr; # Default attributes
|
||||
my %intAt; # Internal at timer hash.
|
||||
my $nextat; # Time when next timer will be triggered.
|
||||
my $intAtCnt=0;
|
||||
my $reread_active = 0;
|
||||
my $AttrList = "room comment";
|
||||
my $cvsid = '$Id: fhem.pl,v 1.49 2008-07-28 12:33:29 rudolfkoenig Exp $';
|
||||
my $cvsid = '$Id: fhem.pl,v 1.50 2008-08-04 13:47:53 rudolfkoenig Exp $';
|
||||
|
||||
$init_done = 0;
|
||||
|
||||
@ -1580,17 +1580,6 @@ HandleTimeout()
|
||||
return ($nextat-$now) if($now < $nextat);
|
||||
|
||||
$nextat = 0;
|
||||
foreach my $i (keys %defs) {
|
||||
next if(!$defs{$i}{TRIGGERTIME});
|
||||
|
||||
if($now >= $defs{$i}{TRIGGERTIME}) {
|
||||
CallFn($i, "TimeFn", $i);
|
||||
} else {
|
||||
$nextat = $defs{$i}{TRIGGERTIME}
|
||||
if(!$nextat || $nextat > $defs{$i}{TRIGGERTIME});
|
||||
}
|
||||
}
|
||||
|
||||
#############
|
||||
# Check the internal list.
|
||||
foreach my $i (keys %intAt) {
|
||||
@ -1631,6 +1620,16 @@ InternalTimer($$$$)
|
||||
$nextat = $tim if(!$nextat || $nextat > $tim);
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
RemoveInternalTimer($)
|
||||
{
|
||||
my ($arg) = @_;
|
||||
foreach my $a (keys %intAt) {
|
||||
delete($intAt{$a}) if($intAt{$a}{ARG} eq $arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
|
Loading…
x
Reference in New Issue
Block a user