diff --git a/fhem/CHANGED b/fhem/CHANGED
index 7ebb1928c..3e6c0b3f8 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,8 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
+ - feature: PRESENCE: MAC address support for mode fritzbox (by Markus M.)
+ - bugfix: PRESENCE: fixing presence detection in mode fritzbox with new
+ Fritz!OS 6.20 (by Markus M.)
- feature: FB_CALLMONITOR: reverse-search attribute is now providing all
possible values, which are selectable (via fhemweb_multiple.js).
see commandref for all possible values
diff --git a/fhem/FHEM/73_PRESENCE.pm b/fhem/FHEM/73_PRESENCE.pm
index 7f4578d18..ec39599be 100755
--- a/fhem/FHEM/73_PRESENCE.pm
+++ b/fhem/FHEM/73_PRESENCE.pm
@@ -1,4 +1,4 @@
-# $Id$
+# $Id$
##############################################################################
#
# 73_PRESENCE.pm
@@ -51,7 +51,7 @@ PRESENCE_Initialize($)
$hash->{DefFn} = "PRESENCE_Define";
$hash->{UndefFn} = "PRESENCE_Undef";
$hash->{AttrFn} = "PRESENCE_Attr";
- $hash->{AttrList}= "do_not_notify:0,1 disable:0,1 fritzbox_repeater:0,1 ping_count:1,2,3,4,5,6,7,8,9,10 powerCmd ".$readingFnAttributes;
+ $hash->{AttrList}= "do_not_notify:0,1 disable:0,1 fritzbox_speed:0,1 ping_count:1,2,3,4,5,6,7,8,9,10 powerCmd ".$readingFnAttributes;
}
@@ -519,7 +519,7 @@ sub PRESENCE_StartLocalScan($;$)
return;
}
- $hash->{STATE} = "active" if($hash->{STATE} eq "???");
+ $hash->{STATE} = "active" if($hash->{STATE} eq "???" or "defined");
if($local == 0)
{
@@ -540,7 +540,7 @@ sub PRESENCE_StartLocalScan($;$)
elsif($mode eq "fritzbox")
{
Log3 $name, 5, "PRESENCE ($name) - starting blocking call for mode fritzbox";
- $hash->{helper}{RUNNING_PID} = BlockingCall("PRESENCE_DoLocalFritzBoxScan", $name."|".$hash->{ADDRESS}."|".$local."|".AttrVal($name, "fritzbox_repeater", "0"), "PRESENCE_ProcessLocalScan", 60, "PRESENCE_ProcessAbortedScan", $hash) unless(exists($hash->{helper}{RUNNING_PID}));
+ $hash->{helper}{RUNNING_PID} = BlockingCall("PRESENCE_DoLocalFritzBoxScan", $name."|".$hash->{ADDRESS}."|".$local."|".AttrVal($name, "fritzbox_speed", "0"), "PRESENCE_ProcessLocalScan", 60, "PRESENCE_ProcessAbortedScan", $hash) unless(exists($hash->{helper}{RUNNING_PID}));
}
elsif($mode eq "shellscript")
{
@@ -635,33 +635,44 @@ sub
PRESENCE_DoLocalFritzBoxScan($)
{
my ($string) = @_;
- my ($name, $device, $local, $repeater) = split("\\|", $string);
+ my ($name, $device, $local, $speedcheck) = split("\\|", $string);
Log3 $name, 5, "PRESENCE_DoLocalFritzBoxScan: $string";
- my $number=0;
+
+ my $number = 0;
+ my $status = 0;
+ my $speed;
- my $check_command = ($repeater ? "active" : "speed");
-
-
- my $status=0;
-
- if (defined($defs{$name}{helper}{cachednr}))
+ my $check_command = ($device =~ /^\s*([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}\s*$/ ? "mac" : "name");
+
+ $device = uc $device if($device =~ /^\s*([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}\s*$/);
+
+ if(defined($defs{$name}{helper}{cachednr}))
{
$number = $defs{$name}{helper}{cachednr};
Log3 $name, 5, "PRESENCE ($name) - try checking $name as device $device with cached number $number";
-
- my $cached_name = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/name");
+ my $cached_name = "";
+
+ $cached_name = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/$check_command");
+
chomp $cached_name;
# only use the cached $number if it has still the correct device name
if($cached_name eq $device)
{
- Log3 $name, 5, "PRESENCE ($name) - checking with cached number the $check_command state ($number)";
- $status = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/$check_command");
-
+ Log3 $name, 5, "PRESENCE ($name) - checking state with cached number ($number)";
+ $status = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/active");
chomp $status;
-
+
+ if($status ne "0" and $speedcheck eq "1")
+ {
+ $speed = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/speed");
+ chomp $speed;
+ Log3 $name, 5, "PRESENCE ($name) - speed check returned: $speed";
+ $speed = undef if($speed eq "0");
+ }
+
Log3 $name, 5, "PRESENCE ($name) - ctlmgr_ctl (cached: $number) returned: $status";
if(not $status =~ /^\s*\d+\s*$/)
@@ -669,11 +680,11 @@ PRESENCE_DoLocalFritzBoxScan($)
return "$name|$local|error|could not execute ctlmgr_ctl (cached)";
}
- return ($status == 0)? "$name|$local|absent|$number" : "$name|$local|present|$number"; ###MH
+ return ($status == 0 ? "$name|$local|absent|$number" : "$name|$local|present|$number").($speedcheck == 1 and defined($speed) ? "|$speed" :"");
}
else
{
- Log3 $name, 5, "PRESENCE ($name) - cached device name ($cached_name) does not match expected name ($device). perform a full scan";
+ Log3 $name, 5, "PRESENCE ($name) - cached device ($cached_name) does not match expected device ($device). perform a full scan";
}
}
@@ -694,27 +705,34 @@ PRESENCE_DoLocalFritzBoxScan($)
while($number <= $max)
{
- $net_device = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/name");
-
+ $net_device = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/$check_command");
+
chomp $net_device;
- Log3 $name, 5, "PRESENCE ($name) - checking with device number $number the $check_command state ($net_device)";
+ Log3 $name, 5, "PRESENCE ($name) - checking device number $number ($net_device)";
if($net_device eq $device)
{
- $status = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/$check_command");
+ $status = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/active");
+ chomp $status;
+
+ if($status ne "0" and $speedcheck eq "1")
+ {
+ $speed = PRESENCE_ExecuteFritzBoxCMD($name, "/usr/bin/ctlmgr_ctl r landevice settings/landevice$number/speed");
+ chomp $speed;
+ Log3 $name, 5, "PRESENCE ($name) - speed check returned: $speed";
+ $speed = undef if($speed eq "0");
+ }
- chomp $status;
-
- Log3 $name, 5, "PRESENCE ($name) - $check_command for device number $net_device is $status";
+ Log3 $name, 5, "PRESENCE ($name) - state for device number $net_device is $status";
+
last;
}
$number++;
-
}
- return ($status == 0 ? "$name|$local|absent" : "$name|$local|present").($number <= $max ? "|$number" : "");
+ return ($status == 0 ? "$name|$local|absent" : "$name|$local|present").($number <= $max ? "|$number" : "|").($speedcheck == 1 and defined($speed) ? "|$speed" : "");
}
@@ -728,7 +746,6 @@ PRESENCE_DoLocalBluetoothScan($)
my $return;
my $wait = 1;
my $ps;
-
my $psargs = "ax";
if(qx(ps --help 2>&1) =~ /BusyBox/g)
@@ -745,7 +762,6 @@ PRESENCE_DoLocalBluetoothScan($)
Log3 $name, 4, "PRESENCE ($name): 'which hcitool' returns: $hcitool";
chomp $hcitool;
-
if(-x $hcitool)
{
while($wait)
@@ -822,10 +838,7 @@ PRESENCE_DoLocalShellScriptScan($)
$return = "$name|$local|error|unexpected script output (expected 0 or 1): $ret";
}
-
-
return $return;
-
}
@@ -882,22 +895,27 @@ PRESENCE_ProcessLocalScan($)
my @a = split("\\|",$string);
my $hash = $defs{$a[0]};
-
- return if($hash->{helper}{DISABLED});
-
+
my $local = $a[1];
my $name = $hash->{NAME};
Log3 $hash->{NAME}, 5, "PRESENCE ($name) - blocking scan result: $string";
+ delete($hash->{helper}{RUNNING_PID});
+
+ if($hash->{helper}{DISABLED})
+ {
+ Log3 $hash->{NAME}, 5, "PRESENCE ($name) - don't process the scan result, as $name is disabled";
+ return;
+ }
+
if(defined($hash->{helper}{RETRY_COUNT}))
{
Log3 $hash->{NAME}, 2, "PRESENCE ($name) - check returned a valid result after ".$hash->{helper}{RETRY_COUNT}." unsuccesful ".($hash->{helper}{RETRY_COUNT} > 1 ? "retries" : "retry");
delete($hash->{helper}{RETRY_COUNT});
}
-
- if($hash->{MODE} eq "fritzbox" and defined($a[3]))
+ if($hash->{MODE} eq "fritzbox" and defined($a[3]) and $a[3] ne "")
{
$hash->{helper}{cachednr} = $a[3] if(($a[2] eq "present") || ($a[2] eq "absent"));
}
@@ -912,10 +930,20 @@ PRESENCE_ProcessLocalScan($)
{
readingsBulkUpdate($hash, "state", "present");
readingsBulkUpdate($hash, "device_name", $a[3]) if(defined($a[3]) and $hash->{MODE} =~ /^(lan-bluetooth|local-bluetooth)$/ );
+
+ if($hash->{MODE} eq "fritzbox" and defined($a[4]))
+ {
+ readingsBulkUpdate($hash, "speed", $a[4]);
+ }
}
elsif($a[2] eq "absent")
{
readingsBulkUpdate($hash, "state", "absent");
+
+ if($hash->{MODE} eq "fritzbox" and defined($a[4]))
+ {
+ readingsBulkUpdate($hash, "speed", $a[4]);
+ }
}
elsif($a[2] eq "error")
{
@@ -927,7 +955,7 @@ PRESENCE_ProcessLocalScan($)
readingsEndUpdate($hash, 1);
- delete($hash->{helper}{RUNNING_PID});
+
#Schedule the next check withing $timeout if it is a regular run
if($local eq "0")
@@ -1013,12 +1041,13 @@ PRESENCE_ProcessAbortedScan($)
define iPhone PRESENCE lan-ping 192.168.179.21
Mode: fritzbox
- define <name> PRESENCE fritzbox <device-name> [ <check-interval> [ <present-check-interval> ] ]
+ define <name> PRESENCE fritzbox <device-name/mac-address> [ <check-interval> [ <present-check-interval> ] ]
- Checks for a network device by requesting the internal state on a FritzBox via ctlmgr_ctl. The device-name must be the same as shown in the network overview of the FritzBox
- This check is only applicaple when FHEM is running on a FritzBox!
+ Checks for a network device by requesting the internal state on a FritzBox via ctlmgr_ctl. The device-name must be the same as shown in the network overview of the FritzBox or can be substituted by the MAC address with the format XX:XX:XX:XX:XX:XX
+ This check is only applicable when FHEM is running on a FritzBox! The detection of absence can take about 10-15 minutes!
Example
- define iPhone PRESENCE fritzbox iPhone-4S
+ define iPhone PRESENCE fritzbox iPhone-6
+ define iPhone PRESENCE fritzbox 00:06:08:05:0D:00
Mode: local-bluetooth
define <name> PRESENCE local-bluetooth <bluetooth-address> [ <check-interval> [ <present-check-interval> ] ]
@@ -1170,14 +1199,12 @@ Options:
define iPhone PRESENCE lan-ping 192.168.179.21define <name> PRESENCE fritzbox <Gerätename> [ <Interval> [ <Anwesend-Interval> ] ]define <name> PRESENCE fritzbox <Gerätename/MAC-Adresse> [ <Interval> [ <Anwesend-Interval> ] ]define iPhone PRESENCE fritzbox iPhone-4Sdefine iPhone PRESENCE fritzbox iPhone-6define iPhone PRESENCE fritzbox 00:06:08:05:0D:00define <name> PRESENCE local-bluetooth <Bluetooth-Adresse> [ <Interval> [ <Anwesend-Interval> ] ]