Life360 - Mapping

Helpful Plugins to contribute to the Indigo community.
User avatar
whmoorejr
Posts: 767
Joined: Tue Jan 15, 2013 11:23 am
Location: Houston, TX

Life360 - Mapping

Post by whmoorejr »

Credit to neilk for pointing me in the right direction for this.

Below is some python bits that can be cut-up however you want. I included examples for geofences and L360 member devices. With this you can:
  • Create a map showing the center point of your geofence and the radius you set in the L360 plugin.
    Create a map with any number of geofences as circles or points or both with any number of member devices.
    Create a map that can show the driving route between any two points (member -> member, geofence -> member, etc.)
    Create a map that can show a banner with the calculated distance between any two points.
You will need an API key (which is free and allows 15,000 requests per month) I included the URL for getting an API key and the URL for additional online documentation in the python bit.
Example generated JPG:
Geofence_Map.jpg
Geofence_Map.jpg (404.07 KiB) Viewed 992 times

Code: Select all

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)
Hopefully someone finds this useful for something.
Bill
My Plugin: My People
ryanbuckner
Posts: 1089
Joined: Sat Oct 08, 2011 12:33 pm
Location: Northern Virginia
Contact:

Re: Life360 - Mapping

Post by ryanbuckner »

whoa. This is awesome. I wonder if theres a way to make this functionality part of the plugin
User avatar
whmoorejr
Posts: 767
Joined: Tue Jan 15, 2013 11:23 am
Location: Houston, TX

Re: Life360 - Mapping

Post by whmoorejr »

ryanbuckner wrote:whoa. This is awesome. I wonder if theres a way to make this functionality part of the plugin
I thought about that too. One trick would be metering it so you wouldn't go above a user's 15,000 asks / day. With multiple devices polling regularly, that would add up quick. Maybe something that only updates every x minutes after the device has traveled y distance... but that would add a lot of overhead to the plugin.

Simplest would be actions where the user could select the devices to map out and put those actions into schedules or triggers.

Either way, it's a bit beyond my abilities with plugin creation. But if you decide to go for it, hopefully what I posted helps out.
Bill
My Plugin: My People
Post Reply

Return to “Ryan Buckner's Plugins”