Tuesday, August 09, 2016

Your Location Automatically Pushed to a Map, Now Robustified

Version 1.0 of my location tracking + Mapalist visualization was functional but not robust enough for use in the backcountry. Essentially, I needed to rework the Tasker code I wrote to support offline and unstable networks. Here's my code to meet these needs:

First, the code that runs to track record your location does so by appending to a local file:

Flag Drop (107)
  A1: If [ %par1 Set ]
  A2: Variable Set [ Name:%note To:%par1 Do Maths:Off Append:Off ] 
  A3: Else 
  A4: Variable Set [ Name:%note To:  Do Maths:Off Append:Off ] 
  A5: End If 
  A6: Get Location [ ... ] 
  A7: Variable Set [ Name:%location To:%LOC ... ] 
  A8: Variable Search Replace [ Variable:%location Search:, ... Replace With:; ] 
  A9: Variable Set [ Name:%data To:%location;%TIMES; ] 
  A10: Write File [ File:Tasker/flags.txt Text:%data ... ] 
  A11: Notify [ Title:Flag Dropped ...] 

The above task, along with recording latitude and longitude, also captures the current Unix timestamp.

For last nights run, I set this up to record my location every 500 steps:

Next, I created a Task that executes and pushes lines of the data file to a Google spreadsheet:

Flags Publish (111)
  A1: Perform Task [ Name:FileGet Priority:%priority
    Parameter 1 (%par1):/sdcard/Tasker/flags.txt
    Parameter 2 (%par2):peek 
    Return Value Variable:%line
    Stop:Off ] 
  A2: If [ %line neq EOF ]
    A3: Spreadsheet Update [ Configuration:Update Where was I? Timeout (Seconds):20 ] 
    A4: Perform Task [ Name:FileGet Priority:%priority
      Parameter 1 (%par1):/sdcard/Tasker/flags.txt
      Parameter 2 (%par2):update
      Return Value Variable:  Stop:Off ] 
    A5: Goto [ Type:Action Number Number:1 Label: ] 
  A6: End If 

This task is made more robust by a generic FileGet task which is noted below. The FileGet tasks pulls a line from a file with the option of either updating the read pointer, or leaving it as is. The result: if there's a problem saving a line to the spreadsheet the process will fail, and when the task tries again it picks up exactly where it left off. Should be nice and robust, so if there is some sort of network issue publishing will be delayed but no data will be lost.

I wired this task into the Wifi Connected state. This means that the process is run automatically when you connect to Wifi and should happen behind the scenes automatically.

Using the the latitude, longitude and Unix timestamp it's possible to create a fairly informative map automatically. Consider the More Info pop-up that's visible when you click on the waypoints from last night's run:

Thankfully, Google has quick answers to quandaries like how do I format a Unix timestamp in Google Sheets? and how do I calculate the distance between latitude and longitude in a Google Sheet?, which make generating the above data surprisingly simple.

Finally, here's the implementation of FileGet which intelligently reads lines from a file in a reliable and repeatable manner:

FileGet (105)
  A1: Variable Set [ Name:%source To:%par1 Do Maths:Off Append:Off ] 
  A2: Variable Set [ Name:%action To:%par2 Do Maths:Off Append:Off ] 
  A3: Test File [ Type:Type Data:%source.pos Store Result In:%type Use Root:Off Continue Task After Error:On ] 
  A4: If [ %type !Set ]
  A5: Write File [ File:%source.pos Text:1 Append:Off Add Newline:On ] 
  A6: End If 
  A7: Read Line [ File:%source.pos Line:1 To Var:%offset ] 
  A8: Read Line [ File:%source Line:%offset To Var:%line ] 
  A9: If [ %action eq update ]
  A10: Variable Set [ Name:%next To:%offset + 1 Do Maths:On Append:Off ] 
  A11: Write File [ File:%source.pos Text:%next Append:Off Add Newline:On ] 
  A12: End If 
  A13: Return [ Value:%line Stop:On ] 

No comments:

Post a Comment