indigo.device.delete("Life360 temp geofence - Bill")
target = "Bill"
tempGeofence = indigo.devices["Life360 temp geofence - Bill"]
members = tempGeofence.states["members_in_geofence"]
if target in members:
return False
else:
return True
###Save Device location to variables:
location1 = indigo.devices[1986325525] # "Life360 - Bill"
lat1 = str(location1.states["member_lat"])
lon1 = str(location1.states["member_long"])
indigo.variable.updateValue(1649518735, value=lat1) # "BillSavedLat"
indigo.variable.updateValue(14927307, value=lon1) # "BillSavedLong"
from math import sqrt, cos, radians
distanceLimit = 2 # <-- quantity, select miles or kilometers below
# Life 360 Member Device Current Location
location1 = indigo.devices[1986325525] # "Life360 - Bill"
lat1 = location1.states["member_lat"]
lon1 = location1.states["member_long"]
# Life 360 Member Device Saved Location
lat2 = float(indigo.variables[1649518735].value) # "BillSavedLat"
lon2 = float(indigo.variables[14927307].value) # "BillSavedLong"
R = 6371 # radius of the earth in km
x = (radians(lon2) - radians(lon1)) * cos(0.5 * (radians(lat2) + radians(lat1)))
y = radians(lat2) - radians(lat1)
kilometers = R * sqrt(x*x + y*y)
miles = kilometers * 0.621371
if miles >= distanceLimit: # <-- change to kilometers or leave as miles
return True
else:
return False
GeoFence Error Exception: 'key body_params not found in dict'
Traceback (most recent call last):
File "plugin.py", line 247, in process_message
self.parseResult(p["device"], p["name"], p["entry"], action_props['body_params'])
KeyError: 'key body_params not found in dict'
from math import sqrt, cos, radians
import requests
appKey = 'putYourFREEapiKeyHere' # get an API key for free at https://developer.mapquest.com/documentation/
urlOpen = 'https://www.mapquestapi.com/staticmap/v5/map?key=' + appKey
urlClose = '&size=600,400@2x&margin=50' # &margin=50' #&zoom=14 #You may have to play the sizing options to get the look you want
##### For examples and for other options: https://developer.mapquest.com/documentation/static-map-api/v5/getting-started/
################################
### Life 360 Geofence Device ###
################################
GF1 = indigo.devices[878566887] # "GeoFence: Home - L360"
GF1latS = GF1.ownerProps["geofence_lat"]
GF1lonS = GF1.ownerProps["geofence_long"]
GF1radS = GF1.ownerProps["geofence_radius"] #Kilometers
GF1lat = float(GF1.ownerProps["geofence_lat"])
GF1lon = float(GF1.ownerProps["geofence_long"])
GF1CircleUrl = '&shape=radius:' + GF1radS + 'km|' + GF1latS +',' + GF1lonS # Geofence Circle
GF1PointUrl = GF1latS + ',' + GF1lonS + '|marker-sm-36ed19-fbf80d-H' # bi-color point for 'H' home.
GF2 = indigo.devices[1052647473] # "GeoFence: HEB - L360"
GF2latS = GF2.ownerProps["geofence_lat"]
GF2lonS = GF2.ownerProps["geofence_long"]
GF2radS = GF2.ownerProps["geofence_radius"] #Kilometers
GF2lat = float(GF2.ownerProps["geofence_lat"])
GF2lon = float(GF2.ownerProps["geofence_long"])
GF2CircleUrl = '&shape=radius:' + GF2radS + 'km|' + GF2latS +',' + GF2lonS
GFTPointUrl = GF2latS + ',' + GF2lonS + '|flag-sm-HEB' # flag with label (5 letter limit, and doesn't like the word home)
##########################
# Life 360 Member Device #
##########################
M1 = indigo.devices[1986325525] # "Life360 - Bill"
M1latS = str(M1.states["member_lat"])
M1lonS = str(M1.states["member_long"])
M1lat = M1.states["member_lat"]
M1lon = M1.states["member_long"]
M1Name = 'BILL'
M1Url = M1latS + ',' + M1lonS + '|flag-sm-' + M1Name
M2 = indigo.devices[989791700] # "Life360 - Annalise"
M2latS = str(M2.states["member_lat"])
M2lonS = str(M2.states["member_long"])
M2lat = M2.states["member_lat"]
M2lon = M2.states["member_long"]
M2Name = 'ANNA'
M2Url = M2latS + ',' + M2lonS + '|flag-sm-' + M2Name
### Format to Combine People for multiple locations
peopleUrl = '&locations=' + M1Url + '||' + M2Url
### Format to show driving route between two points
routeUrl = '&start=' + GF1PointUrl + '&end=' + M2Url + '&routeArc=False&routeColor=812DD3' #False = Street Route. True = Straight line.
##################################################
### Formula to get distance between two points ###
##################################################
R = 6371 # radius of the earth in km
x = (radians(GF1lon) - radians(M2lon)) * cos(0.5 * (radians(GF1lat) + radians(M2lat)))
y = radians(GF1lat) - radians(M2lat)
kilometers = R * sqrt(x*x + y*y)
miles = kilometers * 0.621371
# Round results 2 places past decimal, convert result to string.... make it pretty.
kilometers_string = str(round(kilometers, 2))
miles_string = str(round(miles, 2))
### Format to put distance information on a map in a banner
banner = '&banner=Anna+is+' + kilometers_string + '+km+(' + miles_string + '+miles)+Away|sm'
##############################
### Assemble the final URL ###
##############################
# myURL = urlOpen + GF1CircleUrl + GF2CircleUrl + peopleUrl + urlClose
myURL = urlOpen + GF1CircleUrl + routeUrl + banner + urlClose
###Get the image and save to indigo computer for control page use###
reply = requests.get(myURL)
reply.raise_for_status()
with open('/Users/williammoore/Desktop/Maps/Geofence_Map.jpg', 'wb') as image_file:
image_file.write(reply.content)
from math import sqrt, cos, radians
# Life 360 Member Device
location1 = indigo.devices[1986325525] # "Life360 - Bill"
lat1 = location1.states["member_lat"]
lon1 = location1.states["member_long"]
# Life 360 Geofence Center
location2 = indigo.devices[1052647473] # "GeoFence: HEB - L360"
lat2 = float(location2.ownerProps["geofence_lat"])
lon2 = float(location2.ownerProps["geofence_long"])
R = 6371 # radius of the earth in km
x = (radians(lon2) - radians(lon1)) * cos(0.5 * (radians(lat2) + radians(lat1)))
y = radians(lat2) - radians(lat1)
kilometers = R * sqrt(x*x + y*y)
miles = kilometers * 0.621371
# Round results 2 places past decimal, convert result to string.... make it pretty.
kilometers_string = str(round(kilometers, 2))
miles_string = str(round(miles, 2))
message = "The distance between points is " + kilometers_string + " km (" + miles_string + " miles)"
indigo.server.log(message)
from math import sqrt, cos, radians
trueDistance = 5 # <-- quantity, select miles or kilometers below
if miles >= trueDistance: # <-- change to kilometers or leave as miles
return True
else:
return False
Life360 Debug Updating device: William
Trigger L360 - Bill Arrives Home-Wide
Trigger L360 - Bill Arrives Home-Wide
Trigger L360 - Bill Arrives Home-Wide
Trigger L360 - Bill Arrives Home-Wide
Life360 Debug Updating device: Harper
if (memberCount > prevMemberCount):
lastEnteredTimestamp = cur_date_time
device_states.append({'key': 'last_entered_timestamp','value': lastEnteredTimestamp })
if (memberCount > 0):
if (prevMemberCount == 0):
firstEnteredTimestamp = cur_date_time
device_states.append({'key': 'first_entered_timestamp','value': firstEnteredTimestamp })
elif (memberCount == 0):
if (prevMemberCount > 0):
lastExitedTimestamp = cur_date_time
device_states.append({'key': 'last_existed_timestamp','value': lastExitedTimestamp })
ryanbuckner wrote:I was talking about fences. Gets confusing since a fence is physically a circle, but the term Circle is your group of members. Since the "Place" is already contained on the person, I agree, adding the geofence to the person is redundant. I like the list of people in the geofence. That's handy.
To answer your other question, are you asking about fences or Circles (which are Life360 specific) . If a person is inside 2 fences , the last fence checked by the plugin will show as positive.
I think what I need to do is remove the fence from the person, since there can only be 1. And check each person from the fence
def convertFeetToKm(self, radius_feet):
feet_per_kilometer = 3280.84 # 1 kilometer = 3280.84 feet
return radius_feet / feet_per_kilometer
def isInsideGeoFence(self, device, memberLat, memberLong):
fenceLat = device.pluginProps['geofence_lat']
fenceLong = device.pluginProps['geofence_long']
fenceRadius = device.pluginProps['geofence_radius']
center = Point(fenceLat, fenceLong)
memberPoint = Point(memberLat, memberLong)
distance = great_circle(center, memberPoint).km
return distance <= float(fenceRadius)
phoneCheckMessage = ""
isHome = False
if indigo.devices[989791700].states['member_360_location'] == 'Home' \
and indigo.devices[1986325525].states['member_360_location'] == 'Home' \
and indigo.devices[1085655855].states['member_360_location'] == 'Home' \
and indigo.devices[1532170498].states['member_360_location'] == 'Home' \
and indigo.devices[315152659].states['member_360_location'] == 'Home' \
and indigo.devices[991425392].states['member_360_location'] == 'Home' :
isHome = True
if indigo.devices[989791700].states['member_360_location'] != 'Home':
phoneCheckMessage = phoneCheckMessage + "\t Anna is at: " + indigo.devices[989791700].states['member_360_location'] + ", \n"
if indigo.devices[1986325525].states['member_360_location'] != 'Home':
phoneCheckMessage = phoneCheckMessage + "\t Bill is at: " + indigo.devices[1986325525].states['member_360_location'] + ", \n"
if indigo.devices[1085655855].states['member_360_location'] != 'Home':
phoneCheckMessage = phoneCheckMessage + "\t Harper is at: " + indigo.devices[1085655855].states['member_360_location'] + ", \n"
if indigo.devices[1532170498].states['member_360_location'] != 'Home':
phoneCheckMessage = phoneCheckMessage + "\t Mikey is at: " + indigo.devices[1532170498].states['member_360_location'] + ", \n"
if indigo.devices[315152659].states['member_360_location'] != 'Home':
phoneCheckMessage = phoneCheckMessage + "\t Rylee is at: " + indigo.devices[315152659].states['member_360_location'] + ", \n"
if indigo.devices[991425392].states['member_360_location'] != 'Home':
phoneCheckMessage = phoneCheckMessage + "\t Vikki is at: " + indigo.devices[991425392].states['member_360_location'] + ", \n"
if isHome == True:
phoneCheckMessage = "Everyone is Home."
if isHome == False:
phoneCheckMessage = "Not Everyone is home, \n" + phoneCheckMessage
indigo.server.log(phoneCheckMessage)