GEOFANCY: dual-support for Geofancy.app and Geofency.app
git-svn-id: https://svn.fhem.de/fhem/trunk@4836 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -25,9 +25,12 @@
|
|||||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Version: 1.0.2
|
# Version: 1.1.0
|
||||||
#
|
#
|
||||||
# Major Version History:
|
# Major Version History:
|
||||||
|
# - 1.1.0 - 2014-02-06
|
||||||
|
# -- Support for both apps: Geofency and Geofancy
|
||||||
|
#
|
||||||
# - 1.0.0 - 2014-01-09
|
# - 1.0.0 - 2014-01-09
|
||||||
# -- First release
|
# -- First release
|
||||||
#
|
#
|
||||||
@@ -159,7 +162,11 @@ sub GEOFANCY_Set($@) {
|
|||||||
###################################
|
###################################
|
||||||
sub GEOFANCY_CGI() {
|
sub GEOFANCY_CGI() {
|
||||||
|
|
||||||
# /$infix?device=UUID&id=UUID&latitude=xx.x&longitude=xx.x&trigger=(enter|exit)
|
# Geofancy
|
||||||
|
# /$infix?device=UUIDdev&id=UUIDloc&latitude=xx.x&longitude=xx.x&trigger=(enter|exit)
|
||||||
|
#
|
||||||
|
# Geofency
|
||||||
|
# /$infix?id=UUIDloc&name=locName&entry=(1|0)&date=DATE&latitude=xx.x&longitude=xx.x&device=UUIDdev
|
||||||
my ($request) = @_;
|
my ($request) = @_;
|
||||||
|
|
||||||
my $hash;
|
my $hash;
|
||||||
@@ -170,8 +177,11 @@ sub GEOFANCY_CGI() {
|
|||||||
my $id;
|
my $id;
|
||||||
my $lat;
|
my $lat;
|
||||||
my $long;
|
my $long;
|
||||||
my $trigger;
|
my $entry;
|
||||||
my $msg;
|
my $msg;
|
||||||
|
my $date;
|
||||||
|
my $time;
|
||||||
|
my $locName;
|
||||||
|
|
||||||
# data received
|
# data received
|
||||||
if ( $request =~ m,^(/[^/]+?)(?:\&|\?)(.*)?$, ) {
|
if ( $request =~ m,^(/[^/]+?)(?:\&|\?)(.*)?$, ) {
|
||||||
@@ -197,27 +207,35 @@ sub GEOFANCY_CGI() {
|
|||||||
$webArgs->{$p} = $v;
|
$webArgs->{$p} = $v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !defined( $webArgs->{device} )
|
if (
|
||||||
|
!defined( $webArgs->{device} )
|
||||||
|| !defined( $webArgs->{id} )
|
|| !defined( $webArgs->{id} )
|
||||||
|| !defined( $webArgs->{latitude} )
|
|| (
|
||||||
|| !defined( $webArgs->{longitude} )
|
!(
|
||||||
|| !defined( $webArgs->{trigger} )
|
defined( $webArgs->{trigger} && $webArgs->{trigger} ne "" )
|
||||||
|
)
|
||||||
|
&& !( defined( $webArgs->{entry} ) && $webArgs->{entry} ne "" )
|
||||||
|
)
|
||||||
|| $webArgs->{device} eq ""
|
|| $webArgs->{device} eq ""
|
||||||
|| $webArgs->{id} eq ""
|
|| $webArgs->{id} eq ""
|
||||||
|| $webArgs->{latitude} eq ""
|
)
|
||||||
|| $webArgs->{longitude} eq ""
|
|
||||||
|| $webArgs->{trigger} eq "" )
|
|
||||||
{
|
{
|
||||||
$msg = "device=";
|
$msg = " id=";
|
||||||
$msg .= $webArgs->{device} if ( $webArgs->{device} );
|
|
||||||
$msg .= " id=";
|
|
||||||
$msg .= $webArgs->{id} if ( $webArgs->{id} );
|
$msg .= $webArgs->{id} if ( $webArgs->{id} );
|
||||||
|
$msg .= " name=";
|
||||||
|
$msg .= $webArgs->{name} if ( $webArgs->{name} );
|
||||||
|
$msg .= " entry=";
|
||||||
|
$msg .= $webArgs->{entry} if ( $webArgs->{entry} );
|
||||||
|
$msg .= " trigger=";
|
||||||
|
$msg .= $webArgs->{trigger} if ( $webArgs->{trigger} );
|
||||||
|
$msg .= " date=";
|
||||||
|
$msg .= $webArgs->{date} if ( $webArgs->{date} );
|
||||||
$msg .= " latitude=";
|
$msg .= " latitude=";
|
||||||
$msg .= $webArgs->{latitude} if ( $webArgs->{latitude} );
|
$msg .= $webArgs->{latitude} if ( $webArgs->{latitude} );
|
||||||
$msg .= " longitude=";
|
$msg .= " longitude=";
|
||||||
$msg .= $webArgs->{longitude} if ( $webArgs->{longitude} );
|
$msg .= $webArgs->{longitude} if ( $webArgs->{longitude} );
|
||||||
$msg .= " trigger=";
|
$msg .= " device=";
|
||||||
$msg .= $webArgs->{trigger} if ( $webArgs->{trigger} );
|
$msg .= $webArgs->{device} if ( $webArgs->{device} );
|
||||||
|
|
||||||
Log3 $name, 3,
|
Log3 $name, 3,
|
||||||
"GEOFANCY: Insufficient data received for webhook $link:\n"
|
"GEOFANCY: Insufficient data received for webhook $link:\n"
|
||||||
@@ -227,27 +245,44 @@ sub GEOFANCY_CGI() {
|
|||||||
"NOK\nInsufficient data received for webhook $link:\n" . $msg );
|
"NOK\nInsufficient data received for webhook $link:\n" . $msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
$device = $webArgs->{device};
|
# Geofancy.app
|
||||||
|
if ( defined $webArgs->{trigger} ) {
|
||||||
$id = $webArgs->{id};
|
$id = $webArgs->{id};
|
||||||
|
$entry = $webArgs->{trigger};
|
||||||
$lat = $webArgs->{latitude};
|
$lat = $webArgs->{latitude};
|
||||||
$long = $webArgs->{longitude};
|
$long = $webArgs->{longitude};
|
||||||
$trigger = $webArgs->{trigger};
|
$device = $webArgs->{device};
|
||||||
|
}
|
||||||
|
|
||||||
|
# Geofency.app
|
||||||
|
elsif ( defined $webArgs->{entry} ) {
|
||||||
|
$id = $webArgs->{id};
|
||||||
|
$locName = $webArgs->{name};
|
||||||
|
$entry = $webArgs->{entry};
|
||||||
|
$date = $webArgs->{date};
|
||||||
|
$lat = $webArgs->{latitude};
|
||||||
|
$long = $webArgs->{longitude};
|
||||||
|
$device = $webArgs->{device};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "fatal error";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# no data received
|
# no data received
|
||||||
else {
|
else {
|
||||||
Log3 undef, 3,
|
Log3 undef, 3, "GEOFANCY: No data received";
|
||||||
"GEOFANCY: No data received, see API information on http://wiki.geofancy.com";
|
|
||||||
|
|
||||||
return (
|
return ( "text/plain; charset=utf-8", "NOK No data received" );
|
||||||
"text/plain; charset=utf-8",
|
|
||||||
"NOK No data received, see API information on http://wiki.geofancy.com"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# return error if unknown trigger
|
# return error if unknown trigger
|
||||||
return ( "text/plain; charset=utf-8", "$trigger NOK" )
|
return ( "text/plain; charset=utf-8", "$entry NOK" )
|
||||||
if ( $trigger ne "enter" && $trigger ne "exit" && $trigger ne "test" );
|
if ( $entry ne "enter"
|
||||||
|
&& $entry ne "1"
|
||||||
|
&& $entry ne "exit"
|
||||||
|
&& $entry ne "0"
|
||||||
|
&& $entry ne "test" );
|
||||||
|
|
||||||
$hash = $defs{$name};
|
$hash = $defs{$name};
|
||||||
|
|
||||||
@@ -276,30 +311,36 @@ sub GEOFANCY_CGI() {
|
|||||||
if $hash->{helper}{device_aliases}{$device};
|
if $hash->{helper}{device_aliases}{$device};
|
||||||
|
|
||||||
Log3 $name, 4,
|
Log3 $name, 4,
|
||||||
"GEOFANCY $name: "
|
"GEOFANCY $name: id=$id name=$locName entry=$entry date=$date lat=$lat long=$long dev=$device";
|
||||||
. $device . ": id="
|
|
||||||
. $id
|
|
||||||
. " latitude="
|
|
||||||
. $lat
|
|
||||||
. " longitude="
|
|
||||||
. $long
|
|
||||||
. " trigger="
|
|
||||||
. $trigger;
|
|
||||||
|
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
|
# use time from device
|
||||||
|
if ( defined $date && $date ne "" ) {
|
||||||
|
$hash->{".updateTime"} = GEOFANCY_ISO8601UTCtoLocal($date);
|
||||||
|
$hash->{".updateTimestamp"} = FmtDateTime( $hash->{".updateTime"} );
|
||||||
|
$time = $hash->{".updateTimestamp"};
|
||||||
|
}
|
||||||
|
|
||||||
|
# use local FHEM time
|
||||||
|
else {
|
||||||
|
$time = TimeNow();
|
||||||
|
}
|
||||||
|
|
||||||
# General readings
|
# General readings
|
||||||
readingsBulkUpdate( $hash, "state",
|
readingsBulkUpdate( $hash, "state",
|
||||||
"dev:$device trig:$trigger id:$id lat:$lat long:$long" );
|
"id:$id name:$locName entry:$entry date:$date lat:$lat long:$long dev:$device"
|
||||||
|
);
|
||||||
|
|
||||||
|
$id = $locName if ( defined($locName) && $locName ne "" );
|
||||||
|
|
||||||
readingsBulkUpdate( $hash, "lastDevice", $device );
|
readingsBulkUpdate( $hash, "lastDevice", $device );
|
||||||
readingsBulkUpdate( $hash, "lastArr", $device . " " . $id )
|
readingsBulkUpdate( $hash, "lastArr", $device . " " . $id )
|
||||||
if $trigger eq "enter";
|
if ( $entry eq "enter" || $entry eq "1" );
|
||||||
readingsBulkUpdate( $hash, "lastDep", $device . " " . $id )
|
readingsBulkUpdate( $hash, "lastDep", $device . " " . $id )
|
||||||
if $trigger eq "exit";
|
if ( $entry eq "exit" || $entry eq "0" );
|
||||||
|
|
||||||
my $time = TimeNow();
|
if ( $entry eq "enter" || $entry eq "1" || $entry eq "test" ) {
|
||||||
|
|
||||||
if ( $trigger eq "enter" || $trigger eq "test" ) {
|
|
||||||
Log3 $name, 3, "GEOFANCY $name: $device arrived at $id";
|
Log3 $name, 3, "GEOFANCY $name: $device arrived at $id";
|
||||||
readingsBulkUpdate( $hash, $device, "arrived " . $id );
|
readingsBulkUpdate( $hash, $device, "arrived " . $id );
|
||||||
readingsBulkUpdate( $hash, "currLoc_" . $device, $id );
|
readingsBulkUpdate( $hash, "currLoc_" . $device, $id );
|
||||||
@@ -307,7 +348,7 @@ sub GEOFANCY_CGI() {
|
|||||||
readingsBulkUpdate( $hash, "currLocLong_" . $device, $long );
|
readingsBulkUpdate( $hash, "currLocLong_" . $device, $long );
|
||||||
readingsBulkUpdate( $hash, "currLocTime_" . $device, $time );
|
readingsBulkUpdate( $hash, "currLocTime_" . $device, $time );
|
||||||
}
|
}
|
||||||
if ( $trigger eq "exit" ) {
|
if ( $entry eq "exit" || $entry eq "0" ) {
|
||||||
my $currReading;
|
my $currReading;
|
||||||
my $lastReading;
|
my $lastReading;
|
||||||
|
|
||||||
@@ -343,13 +384,34 @@ sub GEOFANCY_CGI() {
|
|||||||
|
|
||||||
readingsEndUpdate( $hash, 1 );
|
readingsEndUpdate( $hash, 1 );
|
||||||
|
|
||||||
$msg = "$trigger OK";
|
$msg = "$entry OK";
|
||||||
$msg .= "\ndevice=$device id=$id lat=$lat long=$long trigger=$trigger"
|
$msg .= "\ndevice=$device id=$id lat=$lat long=$long trigger=$entry"
|
||||||
if ( $trigger eq "test" );
|
if ( $entry eq "test" );
|
||||||
|
|
||||||
return ( "text/plain; charset=utf-8", $msg );
|
return ( "text/plain; charset=utf-8", $msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub GEOFANCY_ISO8601UTCtoLocal ($) {
|
||||||
|
my ($datetime) = @_;
|
||||||
|
$datetime =~ s/T/ /g if ( defined( $datetime && $datetime ne "" ) );
|
||||||
|
$datetime =~ s/Z//g if ( defined( $datetime && $datetime ne "" ) );
|
||||||
|
|
||||||
|
my (
|
||||||
|
$date, $time, $y, $m, $d, $hour,
|
||||||
|
$min, $sec, $hours, $minutes, $seconds, $timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
( $date, $time ) = split( ' ', $datetime );
|
||||||
|
( $y, $m, $d ) = split( '-', $date );
|
||||||
|
( $hour, $min, $sec ) = split( ':', $time );
|
||||||
|
$m -= 01;
|
||||||
|
$timestamp = timegm( $sec, $min, $hour, $d, $m, $y );
|
||||||
|
( $sec, $min, $hour, $d, $m, $y ) = localtime($timestamp);
|
||||||
|
$timestamp = timelocal( $sec, $min, $hour, $d, $m, $y );
|
||||||
|
|
||||||
|
return $timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
@@ -358,9 +420,12 @@ sub GEOFANCY_CGI() {
|
|||||||
<a name="GEOFANCY"></a>
|
<a name="GEOFANCY"></a>
|
||||||
<h3>GEOFANCY</h3>
|
<h3>GEOFANCY</h3>
|
||||||
<ul>
|
<ul>
|
||||||
Provides webhook receiver for geofencing from geofancy.com.<p>
|
Provides webhook receiver for geofencing via the following iOS apps:<br>
|
||||||
|
<br>
|
||||||
|
<li>Geofency: https://itunes.apple.com/de/app/geofency-time-tracking-automatic/id615538630?l=en&mt=8</li>
|
||||||
|
<li>Geofancy: https://itunes.apple.com/de/app/geofancy/id725198453?l=en&mt=8</li>
|
||||||
|
|
||||||
GEOFANCY is an extension to <a href="FHEMWEB">FHEMWEB</a>. You need to install FHEMWEB to use GEOFANCY.</p>
|
<p>Note: GEOFANCY is an extension to <a href="FHEMWEB">FHEMWEB</a>. You need to install FHEMWEB to use GEOFANCY.</p>
|
||||||
|
|
||||||
<a name="GEOFANCYdefine"></a>
|
<a name="GEOFANCYdefine"></a>
|
||||||
<b>Define</b>
|
<b>Define</b>
|
||||||
|
|||||||
Reference in New Issue
Block a user