ScooterCam Wave Height – Layered Views

Version: 3.0
Author: ScooterCam
For: ScooterCam.net

Clean, discrete layers for buoy observations and forecast models – no more mixing yesterday’s data!

๐ŸŽฏ Why Layered Views?

The Problem with Hybrid

  • Forecast data was bleeding into yesterday
  • Timezone confusion between data sources
  • Hard to see which data is which
  • Mixed data = messy debugging

The Solution: Separate Layers

โœ… Buoy layer = Past 48 hours of real observations
โœ… Forecast layer = Next 48 hours of predictions
โœ… No mixing = No timezone confusion
โœ… Clear data source = Easy debugging


๐ŸŒŠ Three Shortcodes, Three Use Cases

1. [wave_buoy] – Buoy Observations Only

Shows: Past 48 hours of real buoy measurements
When to use: Historical data, validation, actual conditions
Data source: NDBC Buoy 45168 (South Haven)

[wave_buoy]

24

[wave_buoy hours=”24″]

72

[wave_buoy hours=”72″]

[wave_buoy]
[wave_buoy hours="24"]  // Last 24 hours only
[wave_buoy hours="72"]  // Last 3 days

Features:

  • โœ… Real measurements from 12 miles offshore
  • โœ… Current wave stats (height, period, direction)
  • โœ… Solid blue line
  • โœ… Seasonal (April-October)

2. [wave_forecast] – Forecast Only

Shows: Next 48 hours of wave predictions
When to use: Planning, future conditions
Data source: Open-Meteo marine model

[wave_forecast]

[wave_forecast hours=”24″]

[wave_forecast hours=”72″]

[wave_forecast]
[wave_forecast hours="24"]  // Next 24 hours
[wave_forecast hours="72"]  // Next 3 days

Features:

  • โœ… Future predictions from now forward
  • โœ… No historical/yesterday data
  • โœ… Dashed orange line
  • โœ… Year-round availability

3. [wave_layered] – Tabbed Interface

Shows: Both views with tab switcher
When to use: Complete conditions page
Data sources: Both buoy + forecast

[wave_layered]

[wave_layered]

Features:

  • โœ… Tab 1: Buoy Observations (real data)
  • โœ… Tab 2: Forecast Model (predictions)
  • โœ… Single shortcode, both views
  • โœ… Easy switching between layers

๐Ÿ“ฆ Installation

File Structure

/wp-content/plugins/scootercam-wave-layered/
โ”œโ”€โ”€ wave-height-layered.php
โ”œโ”€โ”€ js/
โ”‚   โ””โ”€โ”€ wave-layered-chart.js
โ””โ”€โ”€ README.md

Upload & Activate

  1. Upload to /wp-content/plugins/scootercam-wave-layered/
  2. WordPress Admin โ†’ Plugins โ†’ Activate
  3. Use any of the three shortcodes!

๐ŸŽจ Visual Examples

Buoy Layer (Past Data)

Yesterday โ†โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Now
        48h of observations
        Solid blue line
        Real measurements

Forecast Layer (Future Data)

        Now โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’ +48h
        48h of predictions
        Dashed orange line
        Model forecasts

Layered View (Both)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๐ŸŒŠ Buoy | ๐Ÿ“Š Forecast  โ”‚ โ† Tabs
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                         โ”‚
โ”‚   [Active layer here]   โ”‚
โ”‚                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”ง How It Works

Separate AJAX Endpoints

Buoy Endpoint:

wp_ajax_get_buoy_data
โ†’ Fetches NDBC 45168
โ†’ Returns past X hours
โ†’ Cached 30 minutes

Forecast Endpoint:

wp_ajax_get_forecast_data  
โ†’ Fetches Open-Meteo
โ†’ Returns ONLY future data
โ†’ Cached 1 hour

No More Timezone Issues!

Old hybrid approach:

// Mixed buoy (UTC) + forecast (Chicago)
// Comparison: time() vs strtotime()
// Result: Yesterday bleeds through โŒ

New layered approach:

// Buoy: Shows past only
// Forecast: Shows future only
// No comparison needed โœ…

๐ŸŽฏ Usage Examples

Main Conditions Page

<h1>Lake Michigan Wave Conditions</h1>

<h2>Current Observations</h2>

[wave_buoy hours=”48″]

<h2>48-Hour Forecast</h2>

[wave_forecast hours=”48″]

Tabbed Interface

<h1>Wave Data</h1>

[wave_layered]

Sidebar Widget

<h3>Current Waves</h3>

[wave_buoy hours=”6″]

Blog Post Embed

<p>Check today's wave forecast:</p>

[wave_forecast hours=”24″]

Comparison View

<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
  <div>
    <h3>What Just Happened</h3>

[wave_buoy hours=”24″]

</div> <div> <h3>What’s Coming</h3>

[wave_forecast hours=”24″]

</div> </div>


๐Ÿ“Š Data Specifications

Buoy Layer (45168)

Location: 42.397ยฐN, 86.331ยฐW
Distance: 12 miles west of South Haven
Active: April – October
Update: Hourly

Returns:

  • Wave height (meters)
  • Wave period (seconds)
  • Wave direction (degrees)
  • Timestamps in Chicago timezone

Behavior when offline:

  • Shows friendly message
  • Explains seasonal deployment
  • No chart displayed

Forecast Layer

Location: 42.5593ยฐN, 86.2359ยฐW (South Haven)
Source: Open-Meteo marine model
Active: Year-round
Update: Every 6 hours

Returns:

  • Wave height forecast (meters)
  • Wave period forecast (seconds)
  • Wave direction forecast (degrees)
  • ONLY future timestamps

Filtering:

// Server-side filter
if ($timestamp <= $nowTimestamp) {
    continue; // Skip past data
}

// Guaranteed: Only shows future

๐Ÿ› Troubleshooting

Issue: Forecast Still Shows Yesterday

This shouldn’t happen anymore! But if it does:

  1. Clear transients:
wp transient delete openmeteo_forecast
  1. Check server time:
echo date('Y-m-d H:i:s T');  // Should match reality
  1. Verify timezone:
WordPress Admin โ†’ Settings โ†’ General
Timezone: America/Chicago
  1. Hard refresh:
Ctrl+Shift+R (Windows/Linux)
Cmd+Shift+R (Mac)

Issue: Buoy Shows “Seasonal” Message

This is normal November-April!

The South Haven buoy is physically removed from the water in fall and redeployed in spring. This is expected behavior.

To verify it’s actually off-season:

  • Check: https://www.ndbc.noaa.gov/station_page.php?station=45168
  • Look for recent data (should be none)

Issue: Charts Not Loading

  1. Check browser console (F12):
// Look for errors like:
"Failed to fetch"
"Chart is not a constructor"
"waveLayeredData is not defined"
  1. Verify AJAX endpoints:
# Test buoy endpoint
curl -X POST https://scootercam.net/wp-admin/admin-ajax.php \
  -d "action=get_buoy_data&nonce=..."

# Test forecast endpoint  
curl -X POST https://scootercam.net/wp-admin/admin-ajax.php \
  -d "action=get_forecast_data&nonce=..."
  1. Clear ALL caches:
wp transient delete --all
wp cache flush

๐Ÿ”„ Migration from Hybrid

If Currently Using Hybrid Plugin

Option 1: Run Both (Recommended)

  • Keep hybrid plugin active
  • Install layered plugin
  • Test layered on separate page
  • Gradually migrate

Option 2: Replace Entirely

Old: [wave_hybrid_chart]
New: [wave_layered]

Option 3: Separate Displays

Old: [wave_hybrid_chart]
New: [wave_buoy] + [wave_forecast]

Shortcode Conversion

Old HybridNew Layered
[wave_hybrid_chart][wave_layered]
[wave_hybrid_chart show_buoy="true" show_forecast="false"][wave_buoy]
[wave_hybrid_chart show_buoy="false" show_forecast="true"][wave_forecast]

๐ŸŽจ Customization

Tab Colors

.wave-tab.active {
    background: #10b981; /* Green instead of blue */
}

.wave-tab-badge {
    background: rgba(255,255,255,0.3);
}

Chart Heights

.wave-chart-wrapper {
    height: 500px !important; /* Taller charts */
}

Buoy Chart Color

// In wave-layered-chart.js
borderColor: '#0ea5e9',  // Sky blue instead of blue

Forecast Chart Color

// In wave-layered-chart.js
borderColor: '#8b5cf6',  // Purple instead of orange

๐Ÿ“ˆ Performance

Cache Strategy

Buoy data: 30 minutes

  • Real-time not critical
  • Reduces NDBC server load
  • Balances freshness vs performance

Forecast data: 1 hour

  • Model updates every 6 hours
  • No need for frequent checks
  • Significant performance gain

Load Times

Single layer (buoy or forecast):

  • Initial load: <1 second
  • AJAX call: 1-2 seconds
  • Chart render: <100ms
  • Total: 2-3 seconds

Layered view (tabs):

  • Both layers load on page load
  • Slightly slower: 3-4 seconds
  • But switching tabs is instant

โœ… Advantages Over Hybrid

Data Integrity

  • โœ… No mixed timeframes
  • โœ… No timezone confusion
  • โœ… Clear data boundaries
  • โœ… Easy validation

Debugging

  • โœ… Simple data flow
  • โœ… Separate endpoints
  • โœ… Clear error messages
  • โœ… Isolated failures

User Experience

  • โœ… Choose what to see
  • โœ… Understand data source
  • โœ… No confusing overlaps
  • โœ… Clean visual separation

Maintenance

  • โœ… Easier to update
  • โœ… Independent caching
  • โœ… Clearer code
  • โœ… Better testability

๐Ÿ†š When to Use Which

Use [wave_buoy] when:

  • โœ… Want actual observed data
  • โœ… Validating forecast accuracy
  • โœ… Showing recent trends
  • โœ… It’s buoy season (Apr-Oct)

Use [wave_forecast] when:

  • โœ… Planning future activities
  • โœ… Need predictions
  • โœ… It’s off-season (Nov-Mar)
  • โœ… Want clean forward-looking data

Use [wave_layered] when:

  • โœ… Want complete picture
  • โœ… Professional display
  • โœ… Main conditions page
  • โœ… Let users choose view

๐Ÿ“ Best Practices

Page Layout

Good:

<h1>Wave Conditions</h1>

[wave_layered]

<!– Single comprehensive view –>

Also Good:

<h2>Recent Observations</h2>

[wave_buoy hours=”24″]

<h2>Upcoming Forecast</h2>

[wave_forecast hours=”48″]

<!– Clear separation –>

Avoid:

[wave_layered]

[wave_buoy]

[wave_forecast] <!– Too much! Pick one approach –>

Cache Management

During testing:

# Clear before each test
wp transient delete openmeteo_forecast
wp transient delete ndbc_buoy_45168

In production:

# Let caches work normally
# 30min/1hr is good balance

Seasonal Messaging

April-October (Active):

  • Promote buoy data
  • Show observed stats
  • Highlight “real” measurements

November-March (Inactive):

  • Default to forecast
  • Explain seasonal nature
  • Show “next deployment” date

๐ŸŽ‰ Success Checklist

After deploying layered views:

  • [ ] All three shortcodes work
  • [ ] Buoy shows past data only
  • [ ] Forecast shows future data only
  • [ ] No “yesterday” in forecast
  • [ ] Tabs switch properly (layered view)
  • [ ] Current stats update (buoy view)
  • [ ] Seasonal message shows correctly
  • [ ] Mobile responsive
  • [ ] No console errors
  • [ ] Caching works

๐Ÿ“ž Support

Quick Diagnostics

Test buoy data:

curl https://www.ndbc.noaa.gov/data/realtime2/45168.txt | head -5

Test forecast API:

curl "https://marine-api.open-meteo.com/v1/marine?latitude=42.5593&longitude=-86.2359&hourly=wave_height&timezone=America/Chicago&forecast_days=2" | jq

Check WordPress transients:

wp transient list | grep -E 'buoy|forecast'

๐Ÿ† Summary

Layered = Better than Hybrid because:

  1. Cleaner separation – No data mixing
  2. No timezone issues – Each layer independent
  3. Easier debugging – Isolated data flows
  4. Better UX – Users choose what to see
  5. More reliable – Simpler = fewer bugs

Three shortcodes for every use case:

  • [wave_buoy] โ†’ Past observations
  • [wave_forecast] โ†’ Future predictions
  • [wave_layered] โ†’ Both in tabs

The forecast layer guarantees future-only data! ๐ŸŽฏ


Made with ๐ŸŒŠ for accurate wave forecasting

Verified by MonsterInsights