GithubHelp home page GithubHelp logo

swrobel / meta-surf-forecast Goto Github PK

View Code? Open in Web Editor NEW
300.0 49.0 60.0 4.1 MB

๐ŸŒŠ Modern swell buoy charts + Aggregated surf forecast from Surfline & Spitcast APIs

Home Page: https://metasurfforecast.com

License: MIT License

Ruby 84.25% JavaScript 3.36% HTML 4.83% SCSS 1.09% Slim 6.38% Procfile 0.09%
surf surfline forecast-data surfing ndbc ndbc-buoy-data spitcast surf-forecast

meta-surf-forecast's Introduction

Meta Surf Forecast

Purposes

  1. Display a chart of approximate wave height (swell height * period * 0.1) for the last 24 hours from NDBC Buoys Screenshot
  2. Query the Surfline & Spitcast APIs to display an aggregated surf forecast. Screenshot

Developer Setup

Prerequisites

  • ruby 3.3.x
  • node 20.x
  • yarn 1.x
  • postgresql

Steps

  1. Install dependencies using Homebrew: brew bundle
  2. If on Linux: pg_ctl -D /home/linuxbrew/.linuxbrew/var/postgres start
  3. gem install bundler -v=$(cat Gemfile.lock | tail -1 | tr -d " ")
  4. bundle
  5. yarn
  6. cp config/database.yml.example config/database.yml
  7. bin/rails db:create db:schema:load:with_data db:seed
  8. Grab some data: bin/rails buoys:update forecasts:update
  9. bin/foreman start -f Procfile.dev
  10. Open http://localhost:5000
  11. Any changes you make to view files will auto-reload the browser

Tips

  • You will not get Surfline forecast data without a valid Surfline premium login. Add your credentials to .env.development:
    SURFLINE_EMAIL=xxx
    SURFLINE_PASSWORD=yyy
    
    Then run bin/rails forecasts:update again
  • When running migrations, use bin/rails db:migrate:with_data to include Data Migrations

Adding Spots

Contributing new spots is easy! Make sure you're signed into your Github account and edit the seeds file:

  1. Create a new Region/Subregion if necessary. For example, Los Angeles is created like so:
    CA = Region.find_or_create_by(name: 'California')
    LA = Subregion.find_or_create_by(name: 'Los Angeles', region: CA)
    LA.timezone = 'America/Los_Angeles'
    LA.save!
    You can get valid timezone names from this list.
  2. Use this tool to draw a bounding box around the area you want to find spots for.
  3. Choose CSV from the dropdown at the bottom & copy the coordinates string.
  4. Run rails console, then run SpotFinder.new('{string}').formatted_spots.
  5. Copy the output and paste it into the spots array in seeds.rb, then make sure to assign each spot to the right subregion & delete extraneous fields (msw_name, match_type, distance).
  6. It's strongly encouraged to add all spots for a particular county or region rather than just a single one. Be a pal!
  7. Submit a pull request and I'll get it on the site ASAP!

Use the following as a template. Delete the lines for surfline_v2_id, msw_id, etc, if that spot doesn't exist on that particular site.

  {
    name: 'County Line',
    lat: 34.051,
    lon: -118.964,
    surfline_v2_id: '590927576a2e4300134fbed8',
    msw_id: 277,
    subregion: LA,
  },

Data Sources

New API (v2)

Responses

Surfline's new API is undocumented but easy to reverse engineer using their new website's code. Thankfully its structure is much more sane than the old API.

Requests

https://services.surfline.com/kbyg/spots/forecasts/{type}?{params}

For reference, I believe kbyg stands for "Know Before You Go," which is their tagline.

Type Data
rating array of human-readable and numeric (0-6) ratings
wave array of min/max sizes & optimal scores
wind array of wind directions/speeds & optimal scores
tides array of types & heights
weather array of sunrise/set times, array of temperatures/weather conditions
Param Values Effect
spotId string Surfline spot id that you want data for. A typical Surfline URL is https://www.surfline.com/surf-report/venice-breakwater/590927576a2e4300134fbed8 where 590927576a2e4300134fbed8 is the spotId
days integer Number of forecast days to get (Max 6 w/o access token, Max 17 w/ premium token)
intervalHours integer Minimum of 1 (hour)
maxHeights boolean true seems to remove min & optimal values from the wave data output
sds boolean If true, use the new LOTUS forecast engine
accesstoken string Auth token to get premium data access (optional)

Anywhere there is an optimalScore the value can be interpreted as follows:

Value Meaning
0 Suboptimal
1 Good
2 Optimal

However, I have never seen a score of 1 in any of their API responses (only 0 or 2), which is unfortunate when it comes to granularity of ratings. Hopefully this changes in the future.

Old API (v1 - no longer supported)

Surfline's old API is undocumented and unauthenticated, but was used via javascript on their website, so it was fairly easy to reverse-engineer. However, they have updated their site & apps to use the new API, and it appears that they've stopped including some critical data in the responses for the old API, so it's disabled in this app for now (and probably forever).

It returned JSON, but with a very odd structure, with each item that is time-sensitive containing an array of daily arrays of values that correspond to timestamps provided in a separate set of arrays. For example (lots of data left out for brevity):

"Surf": {
  "dateStamp": [
      [
        "January 24, 2016 04:00:00",
        "January 24, 2016 10:00:00",
        "January 24, 2016 16:00:00",
        "January 24, 2016 22:00:00"
      ],
      [
        "January 25, 2016 04:00:00",
        "January 25, 2016 10:00:00",
        "January 25, 2016 16:00:00",
        "January 25, 2016 22:00:00"
      ]
    ],
  "surf_min": [
      [
        2.15,
        1.8,
        1.4,
        1
      ],
      [
        0.7,
        0.4,
        0.3,
        0.3
      ]
    ],
}

Requests are structured as follows:

https://api.surfline.com/v1/forecasts/{spot_id}?{params}

This is a breakdown of the params available:

Param Values Effect
spot_id integer Surfline spot id that you want data for. A typical legacy Surfline URL is https://www.surfline.com/surf-report/venice-beach-southern-california_4211/ where 4211 is the spot_id. You can also get this from a v2 API response's legacyId property.
resources string Any comma-separated list of "surf,analysis,wind,weather,tide,sort". There could be more available that I haven't discovered. "Sort" gives an array of swells, periods & heights that are used for the tables on spot forecast pages. To see the whole list, just set 'all'.
days integer Number of days of forecast to get. This seems to cap out at 16 for Wind and 25 for Surf.
getAllSpots boolean false returns an object containing the single spot you requested, true returns an array of data for all spots in the same region as your spot, in this case "South Los Angeles"
units string e returns American units (ft/mi), m uses metric
usenearshore boolean The best that I can gather, you want this set to true to use the more accurate nearshore models that take into account how each spot's unique bathymetry affects the incoming swells.
interpolate boolean Provide "forecasts" every 3 hours instead of ever 6. These interpolations seem to be simple averages of the values of the 6-hour forecasts.
showOptimal boolean Includes arrays of 0's & 1's indicating whether each wind & swell forecast is optimal for this spot or not. Unfortunately the optimal swell data is only provided if you include the "sort" resource - it is not included in the "surf" resource.
callback string jsonp callback function name

Spitcast has a documented API.

I've also asked Jack from Spitcast a few questions and added his responses below:

  • Why does the site show a size range, but the API only returns one size value?

    I actually take the API number and create the max by adding 1/6 the height (in feet), and then create the min by subtracting 1/6 the height."

  • All possible values for shape:
    • Poor
    • Poor-Fair
    • Fair
    • Fair-Good
    • Good

MagicSeaweed (no longer supported)

MagicSeaweed was acquired by Surfline an shut down in 2023. Prior to this, MagicSeaweed had a well-documented JSON API that required requesting an API key via email. This was a straightforward process and they got back to me quickly with my key.

I've asked MagicSeaweed a few questions and added their responses below:

  • "Our API provides 5 days of forecast data, with segments of data provided for each 3 hour interval during that 5 day time span."
  • "Our data is updated every 3 hours."

The Magic

Surf quality ratings

All of the forecasting services (including Surfline v1 vs v2) use different systems for rating waves. I've attempted to normalize them all to a 0-5 (6-point) scale as best as possible, which is perhaps easier to understand when mapped onto the commonly-used Poor-Good scale (some throw Epic in there at the top end, but I went with Very Good):

  • 0 => Poor
  • 1 => Poor - Fair
  • 2 => Fair
  • 3 => Fair - Good
  • 4 => Good
  • 5 => Very Good

Each forecasting service is massaged onto that scale as follows:

  • Surfline v2: "Seven point" decimal ratings (0-6). These are massaged by multiplying by 5/6 to get a 0-5 scale.

  • Spitcast: ratings in text form:

    • 0.0 => Poor
    • 0.5 => Poor-Fair
    • 1.0 => Fair
    • 1.5 => Good

    These are massaged by multiplying by 5/1.5 (essentially 3.3ฬ…) to get a 0-5 scale.

For record-keeping, these are the formulae for formerly-supported services:

  • MagicSeaweed: integer fadedRating (0-5) & solidRating (0-5). I simply subtract fadedRating (which is essentially the negative effect of wind) from solidRating.
  • Surfline v1: decimal ratings (0-1) for up to 6 different swells at each spot, as well as an optimalWind boolean. I take the max swell rating at any given time for that spot, multiply it by 5, and then halve it if the wind is not optimal.

Timestamps

It took me a long time to land on a solution here, but I've finally settled on storing all timestamps in the database in the spot's local time. This defies Rails convention, but makes intuitive sense. If you pull up the forecasts table and look at the timestamp, that's the actual local time at that spot that it's forecast for (even though Rails & Postgres both think it's being stored in UTC). This is typically the format that the forecasting service gives it to us in, and what users want to see it in, so there's no point in doing all sorts of fancy conversion when it should be the same all the way through the pipeline. Now, you may ask, why am I still using the Rails default of TIMESTAMP WITHOUT TIMEZONE, and the answer is that shockingly enough, TIMESTAMP WITH TIMEZONE doesn't actually store timezone data!

TODO

  • Figure out a way to convey forecast certainty in charts (ie: most forecasts are in agreement, or they disagree by a wide margin)
  • Explore lazy-loading components
  • Explore SSR for possibly faster browser paint
  • Fetch & display tide/wind/water temperature data from NOAA (they actually have a decent API!)
  • Update Surfline v2 API to use their new 7-point rating scale
  • Improve charts:
    • Fix timestamp formatting.
    • Account for min/max size forecast. Currently charts just reflect the max.
    • Display forecast quality ratings. Perhaps color each bar different depending on how good the rating is. Surfline also has an optimal_wind boolean that is being crudely integrated into the display_swell_rating method - improvements welcome.
  • Fetch & display recent buoy trends that are relevant to each spot to give an idea of when swell is actually arriving.
  • Refresh data on a schedule based on when new data is available (refreshing all forecast sources hourly)
  • Support multiple timezones as opposed to Pacific Time only
  • New Surfline API
  • Stop manually seeding the db and figure out a way to pull all spots from each data source and automatically associate them to a canonical spot record (probably using geocoding)
  • Dark Theme
  • Remove asset pipeline & process CSS w/ webpacker

meta-surf-forecast's People

Contributors

ablelincoln avatar jcohenho avatar smmuirhead100 avatar swrobel avatar tobiastom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meta-surf-forecast's Issues

Couldn't get past step 8 of the install

I think there's a few things missing from the Readme, especially for those who aren't familiar with the invoker gem like myself.

Before being able to run bin/invoker start, you have to first run gem install invoker followed by sudo invoker setup.

Even after doing this, I can't visit https://surf.dev. In chrome I get the following error:
You cannot visit surf.dev right now because the website uses HSTS, and you can't continue beyond this message.

In safari, I get the error Invoker could not find the application. Please check the configuration file..

Python Port and Tweaks

Good day,

I am a college student in Florida and was assigned a homework assignment with the same goal as this project - record surf forecasts. I am not familiar with Ruby and I need a few additional features (like getting data for the NOAA buoys) so I was going to write some Python scripts based off this project. It will be open source and also posted here on GitHub (https://github.com/Legohead259/Surfability-Calculator)

How would you like to be attributed? Would the NOAA API integration be useful to you?

Regards,
-Braidan

Notes from Setting this up [DRAFT]

DRAFT ISSUE - INCOMPLETE

This is a work in progress. I don't currently have the application running locally so I'd assume that the notes here will be useful for future developer one day...

Here I'm just making notes on the difficulties I had while setting this up

  • I had ruby version and bundler issues... so might want to add those to README.md
  • surf.localhost didn't work....
  • I had to run this = brew install terminal-notifier
  • Visiting https://127.0.0.1:3000/ got me this:
2020-09-19 17:39:06 -0500 HTTP parse error, malformed request: #<Puma::HttpParserError: Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?>
2020-09-19 17:39:06 -0500 HTTP parse error, malformed request: #<Puma::HttpParserError: Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?>
  • bin/server specifically works better than conventional rails s
  • This error came up:
    Invoker has detected setup has not been run. Domain feature will not work without running setup command.

Screen Shot 2020-09-20 at 12 25 44 PM

Got it working. Maybe I skipped the step where I was supposed to run the following command:

rvmsudo bin/invoker setup --tld localhost

But I'm pretty sure I did run it previously. Perhaps the order of the setup lines could be adjusted...

Quick question

Hey Stefan!

This isn't necessarily an issue but I was wondering if you could help me with something. So I'm just messing around with Surfline's API and I was wondering if it was possible to access all their surf spots through the API.

I guess more specifically, is it possible to loop through all the surf spots by name and not some long id number?

For example, I'm able to access all the spots in the region of Oahu with:

const res = await fetch("https://services.surfline.com/kbyg/spots/nearby?spotId=5842041f4e65fad6a7708df5");

const data = await res.json();

const oahuSpots = data.data.spots;
console.log(oahuSpots);

How would I go about accessing all the spots in the world? Is this possible for the public?

Thanks in advance!

Spot IDs per country

Hi, is there a way to display all the spots ids on surfline API per country? I'm trying to get that list to have a custom map with all the spots in my country but i cant find the way. Can you help me out?

Question / Request - Ability to query the API for the point in time rating for a specific location

I'd be cool if there was a simple way to send a GET request to the metasurfforecast website for a specific location and get the current surf rating

The reason I am looking for this ability is so that I can display this rating in my TMUX panel. Here's an example of a demo panel shown by https://github.com/gpakosz/.tmux. Not sure if the IMG will show, if not I will upload it. I think there would be multiple other uses as as well

https://user-images.githubusercontent.com/553208/52175490-07797c00-27a5-11e9-9fb6-42eec4fe4188.png

I wanted to do this with MagicSeaWeed but they are being stingy with their API keys. I haven't used .rb before but I can try and raise a PR see what I can do

www.surf-forecast.com

How about this website, it's old looking but for me it's more accurate forecast. Also they have very important option - Wave energy.

Thanks

Feature Request: Timeframe Selector

Hey - great job on this, I find it super useful!

I usually check on mobile to see what the best looking rating is in the county, but it's really difficult to see because the chart lines are so small. If there was a way to select timeframe (1 Day, 2 Days, 3 Days, 1 Week, etc), it would be easier to limit the number of data points on the graph and find the relevant data quickly.

Screen Shot 2020-06-08 at 5 29 52 AM

starting dev environment

When I run invoker start I get this

invoker start

You can enable OSX notification for processes by installing terminal-notifier gem
.guard : Notice: Your terminal-notifier is older than what terminal-notifier-guard supports, consider upgrading.
[BS] Access URLs:


UI: http://localhost:3001


UI External: http://192.168.1.11:3001


[BS] Watching files...
guard : Notice: Your terminal-notifier is older than what terminal-notifier-guard supports, consider upgrading.
00:01:13 - INFO - Bundle already up-to-date
guard : 00:01:13 - INFO - Inspecting Ruby code style of all files
guard : Inspecting 61 files
surf : => Booting Puma
surf : => Rails 5.0.0.1 application starting in development on http://127.0.0.1:9000
surf : => Run rails server -h for more startup options
guard : .............................................................
guard :
guard : 61 files inspected, no offenses detected
guard : 00:01:15 - INFO - Guard is now watching at '/Users/dylanjhaveri/code/meta-surf-forecast'
surf : Puma starting in single mode...
surf : * Version 3.6.0 (ruby 2.3.1-p112), codename: Sleepy Sunday Serenity
surf : * Min threads: 0, max threads: 16
surf : * Environment: development
surf : * Listening on tcp://127.0.0.1:9000
surf : Use Ctrl-C to stop

This looks sane to me, I can see the webapp process surf is running on 9000

When I visit http://127.0.0.1:9000 or http://localhost:9000 I get this error in the invoker output:

Click to expand

surf : 2016-09-01 00:03:10 -0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
surf : 2016-09-01 00:03:10 -0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#IO:, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.6.0 Sleepy Sunday Serenity", "GATEWAY_INTERFACE"=>"CGI/1.2"}
surf : ---
surf : 2016-09-01 00:03:10 -0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
surf : 2016-09-01 00:03:10 -0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#IO:, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.6.0 Sleepy Sunday Serenity", "GATEWAY_INTERFACE"=>"CGI/1.2"}
surf : ---
surf : 2016-09-01 00:03:10 -0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
surf : 2016-09-01 00:03:10 -0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#IO:, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.6.0 Sleepy Sunday Serenity", "GATEWAY_INTERFACE"=>"CGI/1.2"}
surf : ---
surf : 2016-09-01 00:03:10 -0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
surf : 2016-09-01 00:03:10 -0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#IO:, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.6.0 Sleepy Sunday Serenity", "GATEWAY_INTERFACE"=>"CGI/1.2"}
surf : ---
surf : 2016-09-01 00:03:10 -0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
surf : 2016-09-01 00:03:10 -0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#IO:, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.6.0 Sleepy Sunday Serenity", "GATEWAY_INTERFACE"=>"CGI/1.2"}
surf : ---
surf : 2016-09-01 00:03:10 -0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
surf : 2016-09-01 00:03:10 -0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#IO:, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.6.0 Sleepy Sunday Serenity", "GATEWAY_INTERFACE"=>"CGI/1.2"}
surf : ---
surf : 2016-09-01 00:03:10 -0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
surf : 2016-09-01 00:03:10 -0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#IO:, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.6.0 Sleepy Sunday Serenity", "GATEWAY_INTERFACE"=>"CGI/1.2"}
surf : ---

Any idea what I'm doing wrong here? I was able to bundle, seed the database and run rake spitcast:update and rake surfline:update

Surfline API V2

Edit...

Removing the wave, weather, tides e.t.c. give all information in one request...

Thanks for the work on this project and documentation of the different surf API's

I'm working on this product here www.duyvest.com and am looking at adding the surfline API for surf data.

With the V2 api, do you know if it possible to get all the data (wave, tide, weather) with one request? is there a "all" type? I would like to create an approx surf rating using wave height, period and wind speed and direction.

thanks again

Max/Min/Avg Per Source

Hi Stefan

Have or would you released a (365 days or more) dataset or analysis of which one of the sources tend to fall on which end of the range? As in who tends to over/understate surf size more often? Or is there no pattern to this data?

cam api ?

Super cool project. Is there a way to scrape their cam feeds?

Windows compatibility

Hi, I'm a Mac user but am recommending this project to a friend who uses Windows. Do you know if it should work out of the box on Windows? He's a Surfer who is interested in learning SQL, so this is a cool project to explore.

I think the README install procedure is specific to a mac, but the commands should be similar on Windows. If the README.md is the only difference, I can update the documentation after figuring Windows out.

Params problem with Surfline V2

Hi, Great project and thanks for sharing.
I'm having trouble getting the data for Surfline V2 api. It's seems no matter what day or interval hours are set, always return 3 days of forecast with a 3 hours interval. Here is the API :

https://services.surfline.com/kbyg/spots/forecasts/?spotId=5842041f4e65fad6a7708cc2&days=6&intervalHours=1

If days are more than 6 its return :
{
"message": "Parameters out of bounds"
}

but if you use the "conditions" or "report" api, its works, like https://services.surfline.com/kbyg/spots/conditions/?spotId=5842041f4e65fad6a7708cc2&days=6&intervalHours=1

any idea what is happening?

PD: I have a premium account on Surfline but I don't know how to get the Access token, maybe this is a free account issue

Get Legacy ID from Surfline API

I have discovered a way to find a spot's legacy id, and I figured this info might be useful to others.

The Legacy ID can be found by sending a request for a spot report (i.e. https://services.surfline.com/kbyg/spots/reports?spotId=5842041f4e65fad6a7708814 [spot id here is for Rincon]).
This returns a JSON response object, in which the legacy spot id can be accessed from response.associated.advertising.spotId

Surfline API code

I've also been working on a project that utilizes the (hidden) Surfline API. Through my research/snooping around I found that Surfline puts all of their source code straight on their website. I guess they are using source maps and forgot to remove them from the production code. Not the best best security on their end, but I ain't mad. Anyway, all of their API calls are right there for the world to see.

It looks like the api.surfline.com endpoint is actually a deprecated. Devtools shows me that they're now using services.surfline.com, and the config file seems to support this (again, really crappy security having their config file right on their production site).

The good news is we don't have to guess at the API by monitoring their requests, we can just read it straight from the source code. I'll post instructions for how to find the relevant code, as well as some of the code that I've pulled and have found useful so far.

How to view Surfline source code

  1. open Chrome Devtools
  2. go to 'Sources' tab
  3. code is located under webpack:// -> . -> src. Most of the API calls are located in the 'common' folder

I hope this is useful! I think I'll start putting some of this into the meta-surf-forecast code when I get a chance. This is really a cool project!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.