Added surf score
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
GeorgeWebberley 2026-01-28 12:16:40 +01:00
parent 7704532aa9
commit 759f38eae5

View file

@ -13,30 +13,48 @@ const lat = 51.58;
const lon = -4.29;
const marineUrl = `https://marine-api.open-meteo.com/v1/marine?latitude=${lat}&longitude=${lon}&current=swell_wave_height,swell_wave_period,swell_wave_direction,wind_wave_height`;
const weatherUrl = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}&current=wind_speed_10m,wind_direction_10m`;
const tideUrl = `https://flood-api.open-meteo.com/v1/flood?latitude=${lat}&longitude=${lon}&daily=sealevel_max,sealevel_min&hourly=sealevel`;
async function fetchSurfData() {
try {
const [marineRes, weatherRes] = await Promise.all([
const [marineRes, weatherRes, tideRes] = await Promise.all([
axios.get(marineUrl),
axios.get(weatherUrl)
axios.get(weatherUrl),
axios.get(tideUrl)
]);
const currentSwell = marineRes.data.current;
const currentWind = weatherRes.data.current;
const beachTime = new Intl.DateTimeFormat('en-GB', {
hour: 'numeric',
hour12: false,
timeZone: 'Europe/London'
}).format(new Date());
const currentHour = parseInt(beachTime);
const hourlyData = tideRes.data.hourly.sealevel;
const currentTideHeight = hourlyData[currentHour];
const nextHour = (currentHour + 1) % hourlyData.length;
const nextTideHeight = hourlyData[nextHour];
const isPushing = nextTideHeight > currentTideHeight;
const tideDirection = isPushing ? "Pushing" : "Pulling";
const swell = marineRes.data.current;
const wind = weatherRes.data.current;
const finalScore = getSurfScore(swell, wind, isPushing);
const point = new Point('surf_conditions')
.tag('location', 'rhossili_beach')
.floatField('swell_height', currentSwell.swell_wave_height)
.floatField('swell_period', currentSwell.swell_wave_period)
.floatField('swell_direction', currentSwell.swell_wave_direction)
.floatField('wind_speed', currentWind.wind_speed_10m)
.floatField('wind_direction', currentWind.wind_direction_10m);
.tag('location', 'llangennith_beach')
.tag('tide_direction', tideDirection)
.floatField('tide_height', currentTideHeight)
.floatField('swell_height', swell.swell_wave_height)
.floatField('swell_period', swell.swell_wave_period)
.floatField('swell_direction', swell.swell_wave_direction)
.floatField('wind_speed', wind.wind_speed_10m)
.floatField('wind_direction', wind.wind_direction_10m)
.intField('surf_score', finalScore);
writeApi.writePoint(point);
await writeApi.flush();
console.log(`✅ Success: Captured ${currentSwell.swell_wave_height}m swell and ${currentWind.wind_speed_10m}km/h wind.`);
console.log(`📡 Score: ${finalScore}/10 | Tide: ${tideDirection} | Period: ${swell.swell_wave_period}s`);
} catch (error) {
// If it's a connection error, let's be descriptive
if (error.code === 'ECONNREFUSED') {
console.error("❌ Database is not ready yet. Retrying in the next cycle...");
} else {
@ -45,9 +63,28 @@ async function fetchSurfData() {
}
}
// 10 second delay for the very first run to let InfluxDB boot up
function getSurfScore(swell, wind, isPushing){
let score = 5;
if (swell.swell_wave_height < 0.5) {
score = 1;
} else {
if (swell.swell_wave_period >= 9 && swell.swell_wave_period <= 13) score += 2;
else if (swell.swell_wave_period > 13) score += 1;
else if (swell.swell_wave_period < 7) score -= 2;
const isOffshore = wind.wind_direction_10m >= 70 && wind.wind_direction_10m <= 110;
const isOnshore = wind.wind_direction_10m > 190 || wind.wind_direction_10m < 20;
if (isOffshore) score += 3;
else if (isOnshore && wind.wind_speed_10m > 12) score -= 4;
if (isPushing) score += 1;
}
return Math.max(1, Math.min(10, score));
}
console.log("⏳ Fetcher started. Waiting 10s for DB initialization...");
setTimeout(fetchSurfData, 10000);
// Then run every hour
setInterval(fetchSurfData, 1000 * 60 * 60);