Thursday, July 12, 2012

Proximity Sensing Using Latitude and VBScript

Are You Home Yet?
The System Knows...
NOTICE: With the killing of Latitude by Google in 2013, this approach no longer works. Just be advised - too bad, it was a handy solution IMHO. - Stephen

I have played with how to tell my Home Automation system if I was home or away for quite some time. Sure I can press a "home" button and an "away" button but what fun is that for a "Smart" home? I wanted the ability for the system to "know" if I'm home or not "automagically" without my sometimes forgetful intervention.

Back before moving to an iPhone I had a bluetooth solution "semi-working". The phone was paired with a bluetooth adapter on the server and some software was running that could tell if the phone was in range or not. A script would then spin through the status file, a simple flat text file, and see if my phone was local and adjust the status in my system. Kludgy but usually worked.

When I moved to an iPhone I was UNhappy to find out that the same bluetooth option would not work so I was back to figuring out a new solution. This time I wrote a script that "pinged" the IP my phone had picked up on the WiFi and if it was there then I was home, if not, away. That worked but I had to make sure I always had WiFi enabled on the phone and the script simply fired off a command ping which was very slow. Also sometimes the ping would time out anyhow if my phone was not active so I would suddenly be "away" when I was really home.

Google Latitude Tracking

The more recent solution is a combination of using Google Latitude (, which I was already experimenting with, and a local VBScript that provides the linkage between Latitude data and my HA system. Latitude is available for various mobile phones and although obviously very "Big Brotherish" it provides a nice framework to handle the GPS tracking piece of a proximity system. It also provides all kinds of mobility analytics such as how many miles you've traveled, how much time you spend "at work" and "at home" and other rather interesting pieces of information.

To be sure, Latitude is not perfect. It usually has my GPS location pretty well tied down but you will always see occasional "way out there" points when it defaults to the closest cell tower instead of a tight GPS point. But overall it's pretty good at keeping up with where you're at. Personally I haven't see any major battery drainage issues either but I am unrelenting on charging my devices every night no matter how they were used that day.

Of course the first thing you have to do is download the Latitude app for your particular mobile device. Visit the Latitude page and/or your app store and get it working on your device first. There are apps for many of the devices out there so check out the page / links. Make sure the Detect Your Location and Background Updating are turned on in the Settings area so the app is constantly updating location data.

To make Latitude your friend for getting data out, takes a special configuration that isn't overly obvious. You have to expose the data using the "Google Public Location Badge" feature. Sounds like you're giving away the farm but this is just an option if you WANT to publish everywhere you go all the time. The key is, this lets you build the data link but you DON'T HAVE TO share the link. The public location badge allows you to publish either a road map (KML), JSON or ATOM feeds of your location data but we are just going to use the data for our own purposes and not publish to the world.

To get your data link, log into Latitude on the web, click on the gear icon in the upper right, and go to Application Settings. At the very bottom of the screen is a "Developer Information" link. Click on that and you will see the linkage information and your own special username code in the various formats. We are using the JSON format here so the URL looks like this:{Your Code}&type=json

Once you have this link you can leave the rest of the page alone and move on. Just make sure the Enable and Show Best Location radio button is check in the configuration and click Save. That's after you've checked out all the other tidbits of data you'll have available about your movements of course.

Mobile Status Screen for
My Home Automation System

Getting the Data

Now we need to get the data feed and do some location checking. This is where the VBScript comes into play. You can do this in any other scripting or other language if you want, this is just the easiest to write and understand for me. This script is then scheduled on my HA server to run every five (5) minutes to see where I'm at. I actually have it log my Lat/Lon into my own local database and then check for within a certain range of my home address.

VBScript Sample

The key features of the sample script are the GetLatitude and the GetDistance functions. GetLatitude uses your provided Google Latitude user code and pulls the current lat/lon data out of your feed. The GetDistance function takes two lat/lon pairs and returns the distance, in miles, between them. I am using a free online web API to do the distance comparison here but you could spin your own code if you wanted to. is free for the low level personal use I am dealing with here. With those two functions you can have your script do whatever you want with the results. The sample script below uses a CheckDistance variable to compare against the results and take action.

You'll have to clean up some of the &Amp code issues if you copy/paste the script but the overall process is very simple. Also if you are behind a corporate proxy, the URL gets may or may not work. I've run an enhanced version of this script that links to my Home Automation system and toggles my status for months now and it's been quite stable. The code could obviously use some error handling or at least what to do if we get 0,0 back as location or odd distances but that's up to you creative people out there.

'** GetLatitude.vbsGet Google Latitude Lat/Lon for the user and log to the Log database
'v1.00 - SWN - 10/29/2011

'** Debugging flag - True to see messages
MyDebug = TRUE

'** Your information and location to test against
'** Google Latitude User ID
UserID  = "{Your Latitude Code Here}"

'** Location Latitude to test against
LocLat  = 35.32

'** Location Longitude to test against
LocLon  = -96.92

'** If you are within 1/2 Mile of LocLat/LocLon then If triggers
CheckDistance = .5

'** First get the user (YOU) current location from the Latitude JSON feed
MyLonLat = GetLatitude(UserID)

'** Debug stuff - show it if debugging
If MyDebug then MsgBox "Raw Coords: " & MyLonLat

'** Split out the Lat/Lon from the results
MyCoordsA = SPLIT(MyLonLat)
MyLon = MyCoordsA(0)
MyLat = MyCoordsA(1)

'** Now do a distance check between the points
'** Note this uses another free web API, to calc this for us
'** You could build your own dist compare if you wanted... but why if this is there?
'** Distance returned is in Miles so you can convert as desired from there
MyDistance = GetDistance(MyLat, MyLon, LocLat, LocLon)

'** Show distance if debugging
If MyDebug then MsgBox "Distance: " & MyDistance

'** Now take action on the distance check results
'** Obviously you will have to have some session state here so this doesn't fire on every check
'** In my HA system, it sets a Home flag so my code checks if the should be changed and takes action if needed
If MyDistance < CheckDistance then
 '** Do something cool because you're close
 MsgBox "You are within " & MyDistance & " of your target location."
 '** Do something else because you're not
 MsgBox "You are OUTSIDE of your target location by " & MyDistance - CheckDistance & " miles."
End If

'** get the Lat/Lon data from your Google Latitude Feed
Function GetLatitude(strUserID)
 Set objHttp = CreateObject("Msxml2.ServerXMLHTTP")
 objHttp.Open "GET", "" & strUSERID & "&type=json&callback=parse", False
 html = objHttp.ResponseText
 Lines = Split(html, "[", -1, 1)
 MyCoords = lines(2)
 MyCoords = LEFT(MyCoords,INSTR(MyCoords,"]") - 1) 
 GetLatitude = MyCoords
 Set objHTTP = nothing 'Release the object 
End Function

'** Calc the distance between two lat/lon points and return as MILES
Function GetDistance(Lat1, Lon1, Lat2, Lon2)
 Set objHttp = CreateObject("Msxml2.ServerXMLHTTP")
 GetLink = "" & Lat1 & "&lat2=" & Lat2 & "&lng1=" & Lon1 & "&lng2=" & Lon2
 objHttp.Open "GET", GetLink, False
 html = objHttp.ResponseText
 '** Parse out the information here
 StartPos  = Instr(html,"=")
 EndPos   = Instr(html,"mile")
 GetDistance = Ltrim(Rtrim(Mid(html,StartPos + 1, EndPos-StartPos-1)))
 GetDistance = GetDistance * 1
 Set objHttp = Nothing

End Function

Tuesday, May 8, 2012

Mentors of Life

I met a man that I hadn't see for a long time the other day. He was a huge influence for me years ago and I had a chance to catch up on life with him. Thirty plus years ago he gave me opportunities as a "twenty-something" that I would be hard pressed to duplicate today for the younger people I know. I can't imagine handing similar projects over to someone that young that we're so important to a company.

Thirty some years ago, M J Madden [M.J. remembers Pearl Harbor as a child news article]  had a fledgling company called Tel-Elec Consulting Engineers that provided consulting engineering work to then giant Telcos Southwestern Bell and General Telephone. I hired on as a green draftsman just out of high school and trying to go to college. The Engineers would take field notes of where to place cables and a couple of us would take the notes and draw them up to look pretty. That was about it, just drawing up what was already designed, adding title blocks, and nice consistent text by hand. No computers, no Computer Aided Drafting (CAD), just good old by hand drafting.

Life was good, I wasn't sacking groceries anymore but had a "real" job that paid much better than before. This was what I had chosen as my career and I was living it.

Then something funny happened. M.J. and the other engineers started asking ME to go out with them and help TAKE field notes, and then I was being sent out to take field notes on my own to design where cables would be placed and connected to the phone systems. It wasn't just me, their were other draftsmen as well but it felt good, I felt important and subconsciously I guess I wanted more.

Better pay came with the added duties so no complaints there. Even without the added pay I would enjoyed the new learning and accomplishments. Times seemed to move fast. There were good times when had more to do than was possible and there were bad times when it was ok to play frisbee outside for extended times because there wasn't enough work to stay busy but M.J. and the other owners didn't want to let us all go.

Slowly the work came and we were busier than ever. Soon we were in a newly remodeled building and I even had my own OFFICE. I was a twenty something with an office and a well paid job with generous wages and not having to commute an hour each way to work. Life was good.

PDP-11/34 Main CPU
As the company grew, the need to diversify was made and my first exposure to a "computer" came through M.J. Madden and Tel-Elec. The company purchased a DEC PDP 11/34 system for time sharing stepping into the computer age in the early 80's. This was a nearly $100,000 investment back then I understand and before long *I* was actually given an account and allowed to play on this mini computer. Wow. It was very interesting. So interesting that I had to have my own and purchased a Sinclair ZX-81 "kit" that my Dad helped me assemble to learn more about this new world.

Before long I was entering code in the PDP using a BASIC type of language and learning how to program through sample programs and trial and error. I found a "Drag Race" BASIC program that would let you input the horsepower, weight, traction factors, and more and would crank through the calculations to "run the race". It took longer for the program to run than a real drag race did sometimes but it was still pretty cool.

The computer bug was well established and from there on that was my interest. I was given opportunities to update, enhance and write programs for our Time-Share customers and before long we bought PC based computers... not some expensive IBM but CPM-86 computers before the day of the "Standard PC". Quite an amazing time period. A time with ISDN 128kb data speeds were pipe dreams and the "future" of business and homes. I even had a dual channel ISDN circuit at home later on which was quite expensive back then but amazingly fast for the time.

Honestly I owe my career to M.J. Madden who saw a little talent, a little drive, and opened up doors for me to prove, to myself mainly, that I could do it, I could learn, do, and excel at things that the future would bring.

I am still amazed that I was allowed to be responsible for long range outside plant plans, telephone cable air pressurization projects, and the large computer projects that were made available to me in those early times during the 1980's.

It seems so little, so small by comparison to just say "Thanks M.J." for being not only the mentor but providing the opportunities for me to see what I could do during my twelve years with the company.

Stephen W Nolen