Tuesday, April 04, 2017

High or Low? Building a super simple tidal API

Living near the Potomac river, I find it's occasionally useful to know it's current tidal status. Typically, that means mulling over NOAA Tidal Charts like this one:

While reading these charts isn't especially difficult, I did want a quicker way to answer the simple question: is the tide out or in?

Fortunately, NOAA makes the tidal data that powers their charts available for download as CSV (and JSON and XML). You can hit the following URL to get the raw data that powers charts like the one above:

https://tidesandcurrents.noaa.gov/api/datagetter?\
  product=predictions&
  application=NOS.COOPS.TAC.WL&
  station=8594900&
  begin_date=20170402&
  end_date=20170404&
  datum=MLLW&
  units=english&
  time_zone=GMT&
  format=csv

With this data source in place, deriving a quick summary of the current state of the tide is simple. Here's what I do: I request two days worth of data leading up to the current time. I then look for the max and min tide values during that time period and make that my high and low tide values. At the same time I'm crawling through this data, I find the data point in the feed that's closest to the current time. That becomes the current tidal value.

I put that algorithm along with a curl call to pick up the data into this PHP file, and my summary API is complete. For example, consider this command line usage:

$ curl http://code.benjisimon.com/tides/summary.php?station=8594900
0.036L/3.354H/3.004C

That's low tide, high tide and the current level. Note the station value of 8594900 was lifted from NOAA's site and corresponds to a Potomac monitoring station. While I was at it, I implemented JSON output in case I wanted to deal in terms of structured data:

$ curl -s 'http://code.benjisimon.com/tides/summary.php?station=8594900&fmt=json' | jq .
{
  "high": "3.354",
  "low": "0.036",
  "current": "3.004",
  "offset": 102,
  "source": "https://tidesandcurrents.noaa.gov/api/datagetter?product=predictions&application=NOS.COOPS.TAC.WL&station=8594900&begin_date=20170402&end_date=20170404&datum=MLLW&units=english&time_zone=GMT&format=csv"
}

Up next, I'll implement a series of smaller Tasker tasks so that I can quickly get this data on my phone or watch.

No comments:

Post a Comment