>/\n/g;
Log3 $hash->{NAME}, 2, "PRESENCE ($name) - error while processing check: ".$a[3];
}
readingsEndUpdate($hash, 1);
#Schedule the next check within $timeout if it is a regular run
if($local eq "0")
{
my $seconds = (($a[2] eq "present") ? $hash->{INTERVAL_PRESENT} : $hash->{INTERVAL_NORMAL});
$seconds = $hash->{INTERVAL_OVERRIDED} if($hash->{INTERVAL_OVERRIDED});
Log3 $hash->{NAME}, 4, "PRESENCE ($name) - rescheduling next check in $seconds seconds";
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+$seconds, "PRESENCE_StartLocalScan", $hash) unless($hash->{helper}{DISABLED});
}
}
#####################################
sub PRESENCE_ProcessAbortedScan($)
{
my ($hash, $msg) = @_;
my $name = $hash->{NAME};
delete($hash->{helper}{RUNNING_PID});
RemoveInternalTimer($hash);
my $retry_interval = AttrVal($name,"retryInterval",10);
if(defined($hash->{helper}{RETRY_COUNT}))
{
if($hash->{helper}{RETRY_COUNT} >= AttrVal($name, "retryCount", 3))
{
Log3 $hash->{NAME}, 2, "PRESENCE ($name) - device could not be checked after ".$hash->{helper}{RETRY_COUNT}." ".($hash->{helper}{RETRY_COUNT} > 1 ? "retries" : "retry"). " (resuming normal operation): $msg" if($hash->{helper}{RETRY_COUNT} == 3);
InternalTimer(gettimeofday()+$hash->{INTERVAL_NORMAL}, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED});
$hash->{helper}{RETRY_COUNT}++;
}
else
{
Log3 $hash->{NAME}, 2, "PRESENCE ($name) - device could not be checked after ".$hash->{helper}{RETRY_COUNT}." ".($hash->{helper}{RETRY_COUNT} > 1 ? "retries" : "retry")." (retrying in $retry_interval seconds): $msg";
InternalTimer(gettimeofday()+$retry_interval, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED});
$hash->{helper}{RETRY_COUNT}++;
}
}
else
{
$hash->{helper}{RETRY_COUNT} = 1;
InternalTimer(gettimeofday()+$retry_interval, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED});
Log3 $hash->{NAME}, 2, "PRESENCE ($name) - device could not be checked (retrying in $retry_interval seconds): $msg"
}
readingsSingleUpdate($hash, "state", "timeout",1);
}
##########################################################################################################################
#
# Helper Functions
#
##########################################################################################################################
#####################################
sub PRESENCE_DoInit($)
{
my ($hash) = @_;
if(not exists($hash->{helper}{DISABLED}) or (exists($hash->{helper}{DISABLED}) and $hash->{helper}{DISABLED} == 0))
{
readingsSingleUpdate($hash, "state", "active",0);
$hash->{helper}{CURRENT_TIMEOUT} = "normal";
DevIo_SimpleWrite($hash, $hash->{ADDRESS}."|".$hash->{INTERVAL_NORMAL}."\n", 2);
}
else
{
readingsSingleUpdate($hash, "state", "disabled",0);
}
return undef;
}
#####################################
sub PRESENCE_calculateThreshold($)
{
my ($value) = @_;
if(defined($value) and $value ne "")
{
if($value =~ /^(\d?\d):(\d\d)$/)
{
$value = $1 * 60 + $2;
}
elsif($value =~ /^(\d?\d):(\d\d):(\d\d)$/)
{
$value = $1 * 3600 + $2 * 60 + $3;
}
elsif($value !~ /^\d?\d+$/)
{
$value = 0;
}
}
else
{
$value = 0;
}
return $value;
}
#####################################
sub PRESENCE_ThresholdTrigger($)
{
my ($hash) = @_;
if($hash->{helper}{DISABLED})
{
delete($hash->{helper}{NEW_STATE});
return undef;
}
if($hash->{helper}{NEW_STATE})
{
readingsBeginUpdate($hash);
readingsBulkUpdateIfChanged($hash, "state", $hash->{helper}{NEW_STATE});
readingsBulkUpdateIfChanged($hash, "presence", $hash->{helper}{NEW_STATE});
readingsEndUpdate($hash, 1);
$hash->{helper}{CURRENT_STATE} = $hash->{helper}{NEW_STATE};
delete($hash->{helper}{NEW_STATE});
}
}
#####################################
sub PRESENCE_ProcessState($$)
{
my ($hash, $state) = @_;
my $name = $hash->{NAME};
my $current_state = $hash->{helper}{CURRENT_STATE} ? $hash->{helper}{CURRENT_STATE} : "";
my $new_state = $hash->{helper}{NEW_STATE} ? $hash->{helper}{NEW_STATE} : "";
my $absenceThreshold = AttrVal($name, "absenceThreshold", 1);
my $presenceThreshold = AttrVal($name, "presenceThreshold", 1);
my $absenceTimeout = PRESENCE_calculateThreshold(AttrVal($name, "absenceTimeout", ""));
my $presenceTimeout = PRESENCE_calculateThreshold(AttrVal($name, "presenceTimeout", ""));
if($state eq "absent")
{
RemoveInternalTimer($hash, "PRESENCE_ThresholdTrigger");
my $count = ($hash->{helper}{ABSENT_COUNT} ? $hash->{helper}{ABSENT_COUNT} : 0);
if($hash->{MODE} eq "event")
{
if($absenceTimeout > 0 and $current_state ne "absent" and $new_state ne "absent")
{
readingsBulkUpdate($hash, "state", "maybe absent");
readingsBulkUpdate($hash, "presence", "maybe absent");
$hash->{helper}{NEW_STATE} = "absent";
InternalTimer(gettimeofday()+$absenceTimeout, "PRESENCE_ThresholdTrigger", $hash);
}
else
{
readingsBulkUpdate($hash, "state", "absent");
readingsBulkUpdate($hash, "presence", "absent");
$hash->{helper}{CURRENT_STATE} = "absent";
delete($hash->{helper}{NEW_STATE});
}
}
else
{
if(++$count >= $absenceThreshold)
{
readingsBulkUpdate($hash, ".presenceThresholdCounter", 0);
readingsBulkUpdate($hash, ".absenceThresholdCounter", ($count-1));
readingsBulkUpdate($hash, "state", "absent");
readingsBulkUpdate($hash, "presence", "absent");
}
else
{
$hash->{helper}{ABSENT_COUNT} = $count;
readingsBulkUpdate($hash, ".presenceThresholdCounter", 0);
readingsBulkUpdate($hash, ".absenceThresholdCounter", $count);
readingsBulkUpdate($hash, "state", "maybe absent");
readingsBulkUpdate($hash, "presence", "maybe absent");
Log3 $name, 4, "PRESENCE ($name) - device is absent after $count check".($count == 1 ? "" : "s").". ".($absenceThreshold-$count)." check".(($absenceThreshold-$count) == 1 ? "" : "s")." left before going absent";
}
}
delete($hash->{helper}{PRESENT_COUNT});
}
elsif($state eq "present")
{
RemoveInternalTimer($hash, "PRESENCE_ThresholdTrigger");
my $count = ($hash->{helper}{PRESENT_COUNT} ? $hash->{helper}{PRESENT_COUNT} : 0);
if($hash->{MODE} eq "event")
{
if($presenceTimeout > 0 and $current_state ne "present" and $new_state ne "present")
{
readingsBulkUpdate($hash, "state", "maybe present");
readingsBulkUpdate($hash, "presence", "maybe present");
$hash->{helper}{NEW_STATE} = "present";
InternalTimer(gettimeofday()+$presenceTimeout, "PRESENCE_ThresholdTrigger", $hash);
}
else
{
readingsBulkUpdate($hash, "state", "present");
readingsBulkUpdate($hash, "presence", "present");
$hash->{helper}{CURRENT_STATE} = "present";
delete($hash->{helper}{NEW_STATE});
}
}
else
{
if(++$count >= $presenceThreshold)
{
readingsBulkUpdate($hash, ".absenceThresholdCounter", 0);
readingsBulkUpdate($hash, ".presenceThresholdCounter", ($count-1));
readingsBulkUpdate($hash, "state", "present");
readingsBulkUpdate($hash, "presence", "present");
$hash->{helper}{CURRENT_STATE} = "present";
}
else
{
$hash->{helper}{PRESENT_COUNT} = $count;
readingsBulkUpdate($hash, ".absenceThresholdCounter", 0);
readingsBulkUpdate($hash, ".presenceThresholdCounter", $count);
readingsBulkUpdate($hash, "state", "maybe present");
readingsBulkUpdate($hash, "presence", "maybe present");
Log3 $name, 4, "PRESENCE ($name) - device is present after $count check".($count == 1 ? "" : "s").". ".($presenceThreshold-$count)." check".(($presenceThreshold-$count) == 1 ? "" : "s")." left before going present";
}
}
delete($hash->{helper}{ABSENT_COUNT});
}
else
{
readingsBulkUpdate($hash, "state", $state);
}
}
#####################################
sub PRESENCE_ProcessAddonData($$)
{
my ($hash, $data) = @_;
my ($a, $h) = parseParams($data, ";");
foreach my $key (sort keys %{$h})
{
readingsBulkUpdate($hash, $key, $h->{$key}) if(defined($h->{$key}));
}
return undef;
}
#####################################
sub PRESENCE_setNotfiyDev($)
{
my ($hash) = @_;
notifyRegexpChanged($hash,"(global|".$hash->{EVENT_PRESENT}."|".$hash->{EVENT_ABSENT}.")");
}
1;
=pod
=item helper
=item summary provides presence detection checks
=item summary_DE stellt eine Anwesenheitserkennung zur Verfügung
=begin html
PRESENCE
The PRESENCE module provides several possibilities to check the presence of mobile phones or similar mobile devices such as tablets.
This module provides several operational modes to serve your needs. These are:
- lan-ping - A presence check of a device via network ping in your LAN/WLAN.
- fritzbox - A presence check by requesting the device state from the FritzBox internals (only available when running FHEM on a FritzBox!).
- local-bluetooth - A presence check by searching directly for a given bluetooth device nearby.
- function - A presence check by using your own perl function which returns a presence state.
- shellscript - A presence check by using an self-written script or binary which returns a presence state.
- event - A presence check by listening to FHEM events of other definitions.
- lan-bluetooth - A presence check of a bluetooth device via LAN network by connecting to a presenced or collectord instance.
Each mode can be optionally configured with a specific check interval and a present check interval.
- check-interval - The interval in seconds between each presence check. Default value: 30 seconds
- present-check-interval - The interval in seconds between each presence check in case the device is present. Otherwise the normal check-interval will be used.
Define
Mode: lan-ping
define <name> PRESENCE lan-ping <ip-address> [ <check-interval> [ <present-check-interval> ] ]
Checks for a network device via PING requests and reports its presence state.
Example
define iPhone PRESENCE lan-ping 192.168.179.21
Mode: fritzbox
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 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-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> ] ]
Checks for a bluetooth device and reports its presence state. For this mode the shell command "hcitool" is required (provided with a bluez installation under Debian via APT), as well
as a functional bluetooth device directly attached to your machine.
Example
define iPhone PRESENCE local-bluetooth 0a:8d:4f:51:3c:8f
Mode: function
define <name> PRESENCE function {...} [ <check-interval> [ <present-check-interval> ] ]
Checks for a presence state via perl-code. You can use a self-written perl function to obtain the presence state of a specific device (e.g. via SNMP check).
The function must return 0 (absent) or 1 (present). An example can be found in the FHEM-Wiki.
Example
define iPhone PRESENCE function {snmpCheck("10.0.1.1","0x44d77429f35c")}
Mode: shellscript
define <name> PRESENCE shellscript "<path> [<arg1>] [<argN>]..." [ <check-interval> [ <present-check-interval> ] ]
Checks for a presence state via shell script. You can use a self-written script or binary in any language to obtain the presence state of a specific device (e.g. via SNMP check).
The shell must return 0 (absent) or 1 (present) on console (STDOUT). Any other values will be treated as an error
Example
define iPhone PRESENCE shellscript "/opt/check_device.sh iPhone"
Mode: event
define <name> PRESENCE event <absent-regexp> <present-regexp>
Listens for events of other FHEM definitions to determine a presence state. You must provide two event regexp's in the same style as for the notify module.
If an event matches one of the provides regexps, the presence state will be changed.
Example
define Presence_John PRESENCE event Door_Switch:off Door_Switch:on
Mode: lan-bluetooth
Checks for a bluetooth device with the help of presenced or collectord. They can be installed where-ever you like, just must be accessible via network.
The given device will be checked for presence status.
define <name> PRESENCE lan-bluetooth <bluetooth-address> <ip-address>[:port] [ <check-interval> ]
The default port is 5111 (presenced). Alternatly you can use port 5222 (collectord)
Example
define iPhone PRESENCE lan-bluetooth 0a:4f:36:d8:f9:89 127.0.0.1:5222
presenced
The presence is a perl network daemon, which provides presence checks of multiple bluetooth devices over network.
It listens on TCP port 5111 for incoming connections from a FHEM PRESENCE instance or a running collectord.
Usage:
presenced [-d] [-p <port>] [-P <filename>]
presenced [-h | --help]
Options:
-p, --port
TCP Port which should be used (Default: 5111)
-P, --pid-file
PID file for storing the local process id (Default: /var/run/presenced.pid)
-d, --daemon
detach from terminal and run as background daemon
-n, --no-timestamps
do not output timestamps in log messages
-v, --verbose
Print detailed log output
-h, --help
Print detailed help screen
It uses the hcitool command (provided by a bluez installation)
to make a paging request to the given bluetooth address (like 01:B4:5E:AD:F6:D3). The devices must not be visible, but
still activated to receive bluetooth requests.
If a device is present, this is send to FHEM, as well as the device name as reading.
The presenced is available as:
lepresenced
lepresenced is a Perl network daemon that provides presence checks of
multiple bluetooth devices over network. In contrast to presenced,
lepresenced covers Bluetooth 4.0 (low energy) devices, i. e.
Gigaset G-Tags, FitBit Charges.
lepresenced listens on TCP port 5333 for connections of a PRESENCE definition
or collectord.
Usage:
lepresenced --bluetoothdevice <bluetooth device> --listenaddress <listen address> --listenport <listen port> --loglevel <log level> --daemon
lepresenced -b <bluetooth device> -a <listen address> -p <listen port> -l <log level> -d
valid log levels:
LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG. Default: LOG_INFO
Examples:
lepresenced --bluetoothdevice hci0 --listenaddress 127.0.0.1 --listenport 5333 --daemon
lepresenced --loglevel LOG_DEBUG --daemon
To detect the presence of a device, it uses the command hcitool lescan (package:
bluez) to continuously listen to
beacons of Bluetooth LE devices.
If a device is present, this is send to FHEM, as well as the device name as reading.
The presenced is available as:
collectord
The collectord is a perl network daemon, which handles connections to several presenced installations to search for multiple bluetooth devices over network.
It listens on TCP port 5222 for incoming connections from a FHEM presence instance.
Usage:
collectord -c <configfile> [-d] [-p <port>] [-P <pidfile>]
collectord [-h | --help]
Options:
-c, --configfile <configfile>
The config file which contains the room and timeout definitions
-p, --port
TCP Port which should be used (Default: 5222)
-P, --pid-file
PID file for storing the local process id (Default: /var/run/collectord.pid)
-d, --daemon
detach from terminal and run as background daemon
-n, --no-timestamps
do not output timestamps in log messages
-v, --verbose
Print detailed log output
-l, --logfile <logfile>
log to the given logfile
-h, --help
Print detailed help screen
Before the collectord can be used, it needs a config file, where all different rooms, which have a presenced detector, will be listed. This config file looks like:
# room definition
# ===============
#
[room-name] # name of the room
address=192.168.0.10 # ip-address or hostname
port=5111 # tcp port which should be used (5111 is default)
presence_timeout=120 # timeout in seconds for each check when devices are present
absence_timeout=20 # timeout in seconds for each check when devices are absent
[living room]
address=192.168.0.11
port=5111
presence_timeout=180
absence_timeout=20
If a device is present in any of the configured rooms, this is send to FHEM, as well as the device name as reading and the room which has detected the device.
The collectord is available as:
Set
- statusRequest - Schedules an immediatly check.
- power - Executes the given power command which is set as attribute to power (on or off) the device (only when attribute "powerCmd" is set)
- overrideInterval - Override the check interval to the given number of seconds. (not applicable in mode "event" and "lan-bluetooth")
- clearOverride - clear an active check interval override (only if set command overrideInterval was executed before)
Get
Attributes
- do_not_notify
- readingFnAttributes
- disable
If this attribute is activated, an active check will be disabled.
Possible values: 0 => not disabled , 1 => disabled
Default Value is 0 (not disabled)
- absenceThreshold
(not applicable in mode "event" )
The number of checks that have to result in "absent" before the state of the PRESENCE definition is changed to "absent".
This can be used to verify the absence of a device with multiple check runs before the state is finally changed to "absent".
If this attribute is set to a value >1, the reading state and presence will be set to "maybe absent" during the absence verification.
Default Value is 1 (no absence verification)
- presenceThreshold
(not applicable in mode "event" )
The number of checks that have to result in "present" before the state of the PRESENCE definition is changed to "present".
This can be used to verify the permanent presence of a device with multiple check runs before the state is finally changed to "present".
If this attribute is set to a value >1, the reading state and presence will be set to "maybe present" during the presence verification.
Default Value is 1 (no presence verification)
- absenceTimeout
(only in mode "event" applicable)
The timeout after receiving an "absent" event, before the state of the PRESENCE definition is switched to "absent".
This can be used to verify the permanent absence by waiting a specific time frame to not receive an "present" event.
If this timeout is reached with no "present" event received in the meantime, the presence state will finally be set to "absent".
The timeout is given in HH:MM:SS format, where hours and minutes are optional.
If this attribute is set to a valid value, the reading state and presence will be set to "maybe absent" during the absence verification.
Default Value is 0 (no absence verification)
- presenceTimeout
(only in mode "event" applicable)
The timeout after receiving an "present" event, before the state of the PRESENCE definition is switched to "present".
This can be used to verify the permanent presence by waiting a specific time frame to not receive an "absent" event.
If this timeout is reached with no "absent" event received in the meantime, the presence state will finally be set to "present".
The timeout is given in HH:MM:SS format, where hours and minutes are optional.
If this attribute is set to a valid value, the reading state and presence will be set to "maybe present" during the presence verification.
Default Value is 0 (no presence verification)
- retryInterval
(Not applicable in mode "event" or "lan-bluetooth")
The check interval in case a check is prematurely aborted and was unable to check the presence. In this case, PRESENCE reschedules
the next check as retry within the given retry interval in seconds (usually lower than the regular check interval).
Default Value is 10 seconds
- retryCount
(Not applicable in mode "event" or "lan-bluetooth")
The maximum number of checks to perform within the retryInterval in case a check is prematurely aborted and was unable to check the presence.
PRESENCE will try to retry after a failed check to a maximum of the given number of tries. If all retries fails also, it will uses afterwards
the regular check interval.
Default Value is 3 (number of check retries)
- pingCount
(Only in mode "ping" applicable)
Changes the count of the used ping packets to recognize a present state. Depending on your network performance sometimes a packet can be lost or blocked.
Default Value is 4 (packets)
- bluetoothHciDevice
(Only in Mode "local-bluetooth" applicable)
Set a specific bluetooth HCI device to use for scanning. If you have multiple bluetooth modules connected, you can select a specific one to use for scanning (e.g. hci0, hci1, ...).
- fritzboxCheckSpeed
(Only in Mode "fritzbox" applicable)
When this attribute is enabled, the network speed is checked in addition to the device state.
This only makes sense for wireless devices connected directly to the FritzBox.
Possible values: 0 => do not check speed, 1 => check speed when device is active
Default value is 0 (no speed check)
- powerCmd
Define a FHEM command, which powers on or off the device.
When executing the powerCmd (set command: power) following placeholders will be replaced by there corresponding values:
$NAME
- name of the PRESENCE definition
$ADDRESS
- the address of the PRESENCE definition as given in the define statement
$ARGUMENT
- the argument given to the power set command (e.g. "on" or "off)
Example FHEM commands:
set PowerSwitch_1 on
set PowerSwitch_1 $ARGUMENT
"/opt/power_on.sh $ADDRESS"
{powerOn("$ADDRESS", "username", "password")}
Generated readings/events:
General readings/events:
- state: (absent|maybe absent|present|maybe present|disabled|error|timeout) - The state of the device, check errors or "disabled" when the disable attribute is enabled
- presence: (absent|maybe absent|present|maybe present) - The presence state of the device. The value "maybe absent" only occurs if absenceThreshold is activated. The value "maybe present" only occurs if presenceThreshold is activated.
- powerCmd: (executed|failed) - power command was executed or has failed
Bluetooth specific readings/events:
- device_name: $name - The name of the Bluetooth device in case it's present
FRITZ!Box specific readings/events:
- speed: $speed - The current speed of the checked device if attribute fritzboxCheckSpeed is activated
presenced/collectord specific readings/events:
- command_accepted: $command_accepted (yes|no) - Was the last command acknowleged and accepted by the presenced or collectord?
- room: $room - If the module is connected with a collector daemon this event shows the room, where the device is located (as defined in the collectord config file)
=end html
=begin html_DE
PRESENCE
Das PRESENCE Module bietet mehrere Möglichkteiten um die Anwesenheit von Handys/Smartphones oder anderen mobilen Geräten (z.B. Tablets) zu erkennen.
Dieses Modul bietet dazu mehrere Modis an um Anwesenheit zu erkennen. Diese sind:
- lan-ping - Eine Erkennung auf Basis von Ping-Tests im lokalen LAN/WLAN
- fritzbox - Eine Erkennung aufgrund der internen Abfrage des Status auf der FritzBox (nur möglich, wenn FHEM auf einer FritzBox läuft)
- local-bluetooth - Eine Erkennung auf Basis von Bluetooth-Abfragen durch den FHEM Server. Das Gerät muss dabei in Empfangsreichweite sein, aber nicht sichtbar sein
- function - Eine Erkennung mithilfe einer selbst geschriebenen Perl-Funktion, welche den Anwesenheitsstatus ermittelt.
- shellscript - Eine Erkennung mithilfe eines selbst geschriebenen Skriptes oder Programm (egal in welcher Sprache).
- event - Eine Erkennung basierend auf Events einer anderen Definition in FHEM.
- lan-bluetooth - Eine Erkennung durch Bluetooth-Abfragen via Netzwerk (LAN/WLAN) in ein oder mehreren Räumen
Jeder Modus kann optional mit spezifischen Prüf-Intervallen ausgeführt werden.
- check-interval - Das normale Prüfinterval in Sekunden für eine Anwesenheitsprüfung. Standardwert: 30 Sekunden
- present-check-interval - Das Prüfinterval in Sekunden, wenn ein Gerät anwesend (present) ist. Falls nicht angegeben, wird der Wert aus check-interval verwendet
Define
Modus: lan-ping
define <name> PRESENCE lan-ping <IP-Addresse oder Hostname> [ <Interval> [ <Anwesend-Interval> ] ]
Prüft ob ein Gerät über Netzwerk (üblicherweise WLAN) auf Ping-Anfragen reagiert und setzt entsprechend den Anwesenheitsstatus.
Beispiel
define iPhone PRESENCE lan-ping 192.168.179.21
Modus: fritzbox
define <name> PRESENCE fritzbox <Gerätename/MAC-Adresse> [ <Interval> [ <Anwesend-Interval> ] ]
Prüft ob ein Gerät welches per WLAN mit der FritzBox verbunden ist, erreichbar durch Abfrage des Status mit dem Befehl ctlmgr_ctl.
Der Gerätename (Parameter: <Gerätename>) muss dem Namen entsprechen, welcher im Menüpunkt "Heimnetz" auf der FritzBox-Oberfläche angezeigt wird oder kann durch die MAC-Adresse im Format XX:XX:XX:XX:XX:XX ersetzt werden.
Dieser Modus ist nur verwendbar, wenn FHEM auf einer FritzBox läuft! Die Erkennung einer Abwesenheit kann ca. 10-15 Minuten dauern!
Beispiel
define iPhone PRESENCE fritzbox iPhone-6
define iPhone PRESENCE fritzbox 00:06:08:05:0D:00
Modus: local-bluetooth
define <name> PRESENCE local-bluetooth <Bluetooth-Adresse> [ <Interval> [ <Anwesend-Interval> ] ]
Prüft ob ein Bluetooth-Gerät abgefragt werden kann und meldet dies als Anwesenheit. Für diesen Modus wird der Shell-Befehl "hcitool" benötigt
(wird durch das Paket bluez bereitgestellt), sowie ein funktionierender Bluetooth-Empfänger (intern oder als USB-Stick)
Beispiel
define iPhone PRESENCE local-bluetooth 0a:4f:36:d8:f9:8
Modus: function
define <name> PRESENCE function {...} [ <Interval> [ <Anwesend-Interval> ] ]
Prüft den Anwesenheitsstatus mithilfe einer selbst geschriebenen Perl-Funktion (z.B. SNMP Abfrage).
Diese Funktion muss 0 (Abwesend) oder 1 (Anwesend) zurückgeben. Ein entsprechendes Beispiel findet man im FHEM-Wiki.
Beispiel
define iPhone PRESENCE function {snmpCheck("10.0.1.1","0x44d77429f35c")
Mode: shellscript
define <name> PRESENCE shellscript "<Skript-Pfad> [<arg1>] [<argN>]..." [ <Interval> [ <Anwesend-Interval> ] ]
Prüft den Anwesenheitsstatus mithilfe eines selbst geschrieben Skripts oder Programmes (egal in welcher Programmier-/Skriptsprache)
Der Aufruf dieses Skriptes muss eine 0 (Abwesend) oder 1 (Anwesend) auf der Kommandozeile (STDOUT) ausgeben. Alle anderen Werte/Ausgaben werden als Fehler behandelt.
Beispiel
define iPhone PRESENCE shellscript "/opt/check_device.sh iPhone"
Mode: event
define <name> PRESENCE event <Abwesend-Regexp> <Anwesend-Regexp>
Lauscht auf Events von anderen Definitionen innerhalb von FHEM um die Anwesenheit darzustellen.
Die regulären Ausdrücke für An- und Abwesenheit entsprechen dabei der Syntax von notify.
Sobald innerhalb von FHEM ein Event gefeuert wird, welches auf die Abwesend-Regexp bzw. Anwesend-Regexp passt, wird der Status entsprechend in PRESENCE gesetzt.
Beispiel
define Anwesenheit PRESENCE event Tuerschalter:off Tuerschalter:on
Modus: lan-bluetooth
Prüft ein Bluetooth-Gerät auf Anwesenheit über Netzwerk mit Hilfe von presenced oder collectord. Diese können auf jeder Maschine installiert werden,
welche eine Standard-Perl-Umgebung bereitstellt und über Netzwerk erreichbar ist.
define <name> PRESENCE lan-bluetooth <Bluetooth-Adresse> <IP-Adresse>[:Port] [ <Interval> ]
Der Standardport ist 5111 (presenced). Alternativ kann man den Port 5222 (collectord) nutzen. Generell ist der Port aber frei wählbar.
Beispiel
define iPhone PRESENCE lan-bluetooth 0a:4f:36:d8:f9:89 127.0.0.1:5222
presenced
Der presenced ist ein Perl Netzwerkdienst, welcher eine Bluetooth-Anwesenheitserkennung von ein oder mehreren Geräten über Netzwerk bereitstellt.
Dieser lauscht standardmäßig auf TCP Port 5111 nach eingehenden Verbindungen von dem PRESENCE Modul oder einem collectord.
Usage:
presenced -d [-p <port>] [-P <filename>]
presenced [-h | --help]
Options:
-p, --port
TCP Port which should be used (Default: 5111)
-P, --pid-file
PID file for storing the local process id (Default: /var/run/presenced.pid)
-d, --daemon
detach from terminal and run as background daemon
-v, --verbose
Print detailed log output
-h, --help
Print detailed help screen
Zur Bluetooth-Abfrage wird der Shell-Befehl "hcitool" verwendet (Paket: bluez)
um sogenannte "Paging-Request" an die gewünschte Bluetooth Adresse (z.B. 01:B4:5E:AD:F6:D3) durchzuführen. Das Gerät muss dabei nicht sichtbar sein, allerdings ständig aktiviert sein
um Bluetooth-Anfragen zu beantworten.
Wenn ein Gerät anwesend ist, wird dies an FHEM übermittelt zusammen mit dem Gerätenamen als Reading.
Der presenced ist zum Download verfügbar als:
lepresenced
lepresenced ist ein Perl Netzwerkdienst, der analog zu presenced eine
Bluetooth-Anwesenheitserkennung von ein oder mehreren Geräten
über Netzwerk bereitstellt. Im Gegensatz zu presenced unterstützt
lepresenced Bluetooth 4.0 (Low Energy) Geräte wie z. B. Gigaset G-Tags,
FitBit Charges.
lepresenced lauscht standardmäßig auf TCP Port 5333 und wartet
auf eingehende Verbindungen des PRESENCE-Moduls bzw. von collectord.
Usage:
lepresenced --bluetoothdevice <bluetooth device> --listenaddress <listen address> --listenport <listen port> --loglevel <log level> --daemon
lepresenced -b <bluetooth device> -a <listen address> -p <listen port> -l <log level> -d
valid log levels:
LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG. Default: LOG_INFO
Examples:
lepresenced --bluetoothdevice hci0 --listenaddress 127.0.0.1 --listenport 5333 --daemon
lepresenced --loglevel LOG_DEBUG --daemon
Zur Bluetooth-Abfrage wird der Befehl hcitool lescan (Paket:
bluez) verwendet, der
fortwährend auf die Beacons der Bluetooth-LE-Geräte lauscht.
Wenn ein Gerät anwesend ist, wird dies an FHEM übermittelt zusammen mit dem Gerätenamen als Reading.
Der le presenced ist zum Download verfügbar als:
collectord
Der collectord ist ein Perl Netzwerk Dienst, welcher Verbindungen zu mehreren presenced-Instanzen verwaltet um eine koordinierte Suche nach ein oder mehreren Bluetooth-Geräten über Netzwerk durchzuführen.
Er lauscht auf TCP port 5222 nach eingehenden Verbindungen von einem PRESENCE Modul.
Usage:
collectord -c <configfile> [-d] [-p <port>] [-P <pidfile>]
collectord [-h | --help]
Options:
-c, --configfile <configfile>
The config file which contains the room and timeout definitions
-p, --port
TCP Port which should be used (Default: 5222)
-P, --pid-file
PID file for storing the local process id (Default: /var/run/collectord.pid)
-d, --daemon
detach from terminal and run as background daemon
-v, --verbose
Print detailed log output
-l, --logfile <logfile>
log to the given logfile
-h, --help
Print detailed help screen
Bevor der collectord verwendet werden kann, benötigt er eine Konfigurationsdatei in welcher alle Räume mit einem presenced-Agenten eingetragen sind. Diese Datei sieht wie folgt aus:
# Raum Definitionen
# =================
#
[Raum-Name] # Name des Raumes
address=192.168.0.10 # IP-Adresse oder Hostname
port=5111 # TCP Port welcher benutzt werden soll (standardmäßig 5111)
presence_timeout=120 # Prüfinterval in Sekunden für jede Abfrage eines Gerätes, welches anwesend ist
absence_timeout=20 # Prüfinterval in Sekunden für jede Abfrage eines Gerätes, welches abwesend ist
[Wohnzimmer]
address=192.168.0.11
port=5111
presence_timeout=180
absence_timeout=20
Wenn ein Gerät in irgend einem Raum anwesend ist, wird dies an FHEM übermittelt, zusammen mit dem Gerätenamen und dem Raum, in welchem das Gerät erkannt wurde.
Der collectord ist zum Download verfügbar als:
Set
- statusRequest - Startet einen sofortigen Check.
- power - Startet den powerCmd-Befehl welche durch den Parameter powerCmd angegeben ist (Nur wenn das Attribut "powerCmd" definiert ist)
- overrideInterval - Übersteuert das Prüfinterval auf die übergebene Dauer in Sekunden (Nicht im Modus "event" und "lan-bluetooth" anwendbar)
- clearOverride - Entfernt eine zuvor gesetzte Übersteuerung des Prüfintervals (Nur anwendbar, wenn zuvor eine Übersteuerung mit dem Set-Befehl overrideInterval stattgefunden hat)
Get
Attributes
- do_not_notify
- readingFnAttributes
- disable
Wenn dieses Attribut aktiviert ist, wird die Anwesenheitserkennung nicht mehr durchgeführt.
Mögliche Werte: 0 => Erkennung durchführen , 1 => Keine Erkennungen durchführen
Standardwert ist 0 (Erkennung durchführen)
- absenceThreshold
(Nicht im Modus "event" anwendbar)
Die Anzahl an Checks, welche in "absent" resultieren müssen, bevor der Status der PRESENCE-Definition auf "absent" wechselt.
Mit dieser Funktion kann man die Abwesenheit eines Gerätes verifizieren bevor der Status final auf "absent" geändert wird.
Wenn dieses Attribut auf einen Wert >1 gesetzt ist, werden die Readings "state" und "presence" auf den Wert "maybe absent" gesetzt,
bis der Status final auf "absent" wechselt.
Standardwert ist 1 (keine Abwesenheitsverifizierung)
- presenceThreshold
(Nicht im Modus "event" anwendbar)
Die Anzahl an Checks, welche in "present" resultieren müssen, bevor der Status der PRESENCE-Definition auf "present" wechselt.
Mit dieser Funktion kann man die Anwesenheit eines Gerätes verifizieren bevor der Status final auf "present" geändert wird.
Wenn dieses Attribut auf einen Wert >1 gesetzt ist, werden die Readings "state" und "presence" auf den Wert "maybe present" gesetzt,
bis der Status final auf "present" wechselt.
Standardwert ist 1 (keine Anwesenheitsverifizierung)
- absenceTimeout
(Nur im Modus "event" anwendbar)
Die Dauer, die nach einem "absent"-Event gewartet werden soll, bis der Status der PRESENCE-Definition tatsächlich auf "absent" geändert werden soll.
Die Dauer kann dabei im Format HH:MM:SS angegeben werden, wobei Stunden und Minuten optional sind.
Wenn dieses Attribut auf einen gültigen Wert gesetzt ist, werden die Readings "state" und "presence" bei einem "absent"-Event zunächst auf den Wert "maybe absent" gesetzt.
Sobald das parametrisierte Zeitfenster um ist, wird der Status final auf "absent" gesetzt.
Standardwert ist 0 Sekunden (keine Statusverzögerung)
- presenceTimeout
(Nur im Modus "event" anwendbar)
Die Dauer, die nach einem "present"-Event gewartet werden soll, bis der Status der PRESENCE-Definition tatsächlich auf "present" geändert werden soll.
Die Dauer kann dabei im Format HH:MM:SS angegeben werden, wobei Stunden und Minuten optional sind.
Wenn dieses Attribut auf einen gültigen Wert gesetzt ist, werden die Readings "state" und "presence" bei einem "present"-Event zunächst auf den Wert "maybe present" gesetzt.
Sobald das parametrisierte Zeitfenster um ist, wird der Status final auf "present" gesetzt.
Standardwert ist 0 Sekunden (keine Statusverzögerung)
- retryInterval
(Nicht im Modus "event" oder "lan-bluetooth" anwendbar)
Das Prüfinterval, welches im Falle eines vorzeitig abgebrochenen Checks genutzt wird, um eine Wiederholung auszuführen. Dazu wird im Falle eines abgebrochenen
Checks der nächste Check nach der übergebenen Dauer in Sekunden ausgeführt. Diese sollte geringer sein als das reguläre Prüfinterval.
Standardwert ist 10 Sekunden
- retryCount
(Nicht im Modus "event" oder "lan-bluetooth" anwendbar)
Die maximale Anzahl an Wiederholungen, sollte ein Check vorzeitig abgebrochen werden. Sobald ein Check vorzeitigabbricht, werden maximal die übergebene Anzahl an Wiederholung
innerhalb des in retryInterval konfigurierten Interval ausgeführt um in kürzerer Zeit ein valides Ergebnis zu erhalten.
Standardwert ist 3 Wiederholungen
- pingCount
(Nur im Modus "ping" anwendbar)
Verändert die Anzahl der Ping-Pakete die gesendet werden sollen um die Anwesenheit zu erkennen.
Je nach Netzwerkstabilität können erste Pakete verloren gehen oder blockiert werden.
Standardwert ist 4 (Versuche)
- bluetoothHciDevice
(Nur im Modus "local-bluetooth" anwendbar)
Sofern man mehrere Bluetooth-Empfänger verfügbar hat, kann man mit diesem Attribut ein bestimmten Empfänger auswählen, welcher zur Erkennung verwendet werden soll (bspw. hci0, hci1, ...). Es muss dabei ein vorhandener HCI-Gerätename angegeben werden wie z.B. hci0
.
- fritzboxCheckSpeed
(Nur im Modus "fritzbox")
Zusätzlich zum Status des Geräts wird die aktuelle Verbindungsgeschwindigkeit ausgegeben
Das macht nur bei WLAN Geräten Sinn, die direkt mit der FritzBox verbunden sind. Bei abwesenden Geräten wird als Geschwindigkeit 0 ausgegeben.
Mögliche Werte: 0 => Geschwindigkeit nicht prüfen, 1 => Geschwindigkeit prüfen
Standardwert ist 0 (Keine Geschwindigkeitsprüfung)
- powerCmd
Ein FHEM-Befehl, welcher das Gerät schalten kann.
Wenn der power-Befehl ausgeführt wird (set-Befehl: power) werden folgende Platzhalter durch ihre entsprechenden Werte ersetzt:
$NAME
- Name der PRESENCE-Definition
$ADDRESS
- Die überwachte Addresse der PRESENCE Definition, wie sie im define-Befehl angegeben wurde.
$ARGUMENT
- Das Argument, was dem Set-Befehl "power" übergeben wurde. (z.B. "on" oder "off")
Beispielhafte FHEM-Befehle:
set PowerSwitch_1 on
set PowerSwitch_1 $ARGUMENT
"/opt/power_on.sh $ADDRESS"
{powerOn("$ADDRESS", "username", "password")}
Generierte Readings/Events:
Generelle ReadingsEvents:
- state: (absent|maybe absent|present|maybe present|disabled|error|timeout) - Der Anwesenheitsstatus eine Gerätes (absent = abwesend; present = anwesend) oder "disabled" wenn das disable-Attribut aktiviert ist
- presence: (absent|maybe absent|present|maybe present) - Der Anwesenheitsstatus eine Gerätes (absent = abwesend; present = anwesend). Der Wert "maybe absent" (vielleicht abwesend) tritt nur auf, sofern das Attribut absenceThreshold aktiviert ist. Der Wert "maybe present" (vielleicht anwesend) tritt nur auf, sofern das Attribut presenceThreshold aktiviert ist.
- powerCmd: (executed|failed) - Ausführung des power-Befehls war erfolgreich.
Bluetooth-spezifische Readings/Events:
- device_name: $name - Der Name des Bluetooth-Gerätes, wenn es anwesend (Status: present) ist
FRITZ!Box-spezifische Readings/Events:
- speed: $speed - Die Netzwerkdeschwindigkeit des Gerätes, sofern das Attribut fritzboxCheckSpeed aktiviert ist.
presenced-/collectord-spezifische Readings/Events:
- command_accepted: $command_accepted (yes|no) - Wurde das letzte Kommando an den presenced/collectord akzeptiert (yes = ja, no = nein)?
- room: $room - Wenn das Modul mit einem collectord verbunden ist, zeigt dieses Event den Raum an, in welchem dieses Gerät erkannt wurde (Raumname entsprechend der Konfigurationsdatei des collectord)
=end html_DE
=cut