started working on OpenMeteo

main
Fran314 4 weeks ago
parent 4ddc0ba163
commit 1f8fcb3273

@ -21,17 +21,17 @@ The scraper collects data and arranges in the following scheme
{ {
"today": { "today": {
"[0..23]": { "[0..23]": {
"temp": { "temperature": {
"type": "number", "type": "number",
"unitOfMeasurement": "degrees", "unitOfMeasurement": "degrees",
"description": "expected temperature at the given hour" "description": "expected temperature at the given hour"
}, },
"prec": { "precipitation": {
"type": "number", "type": "number",
"unitOfMeasurement": "mm", "unitOfMeasurement": "mm",
"description": "expected precipitation at the given hour" "description": "expected precipitation at the given hour"
}, },
"code": { "weatherCode": {
"type": "string", "type": "string",
"description": "weather code (sunny / cloudy / ...)" "description": "weather code (sunny / cloudy / ...)"
} }
@ -39,17 +39,17 @@ The scraper collects data and arranges in the following scheme
}, },
"tomorrow": { "tomorrow": {
"[0..23]": { "[0..23]": {
"temp": { "temperature": {
"type": "number", "type": "number",
"unitOfMeasurement": "degrees", "unitOfMeasurement": "degrees",
"description": "expected temperature at the given hour" "description": "expected temperature at the given hour"
}, },
"prec": { "precipitation": {
"type": "number", "type": "number",
"unitOfMeasurement": "mm", "unitOfMeasurement": "mm",
"description": "expected precipitation at the given hour" "description": "expected precipitation at the given hour"
}, },
"code": { "weatherCode": {
"type": "string", "type": "string",
"description": "weather code (sunny / cloudy / ...)" "description": "weather code (sunny / cloudy / ...)"
} }
@ -57,17 +57,17 @@ The scraper collects data and arranges in the following scheme
}, },
"dayAfterTomorrow": { "dayAfterTomorrow": {
"[0..23]": { "[0..23]": {
"temp": { "temperature": {
"type": "number", "type": "number",
"unitOfMeasurement": "degrees", "unitOfMeasurement": "degrees",
"description": "expected temperature at the given hour" "description": "expected temperature at the given hour"
}, },
"prec": { "precipitation": {
"type": "number", "type": "number",
"unitOfMeasurement": "mm", "unitOfMeasurement": "mm",
"description": "expected precipitation at the given hour" "description": "expected precipitation at the given hour"
}, },
"code": { "weatherCode": {
"type": "string", "type": "string",
"description": "weather code (sunny / cloudy / ...)" "description": "weather code (sunny / cloudy / ...)"
} }
@ -75,22 +75,22 @@ The scraper collects data and arranges in the following scheme
}, },
"week": { "week": {
"[0..6]": { "[0..6]": {
"minTemp": { "minimumTemperature": {
"type": "number", "type": "number",
"unitOfMeasurement": "degrees", "unitOfMeasurement": "degrees",
"description": "minimum expected temperature for the day" "description": "minimum expected temperature for the day"
}, },
"maxTemp": { "maximumTemperature": {
"type": "number", "type": "number",
"unitOfMeasurement": "degrees", "unitOfMeasurement": "degrees",
"description": "maximum expected temperature for the day" "description": "maximum expected temperature for the day"
}, },
"totPrec": { "precipitationSum": {
"type": "number", "type": "number",
"unitOfMeasurement": "mm", "unitOfMeasurement": "mm",
"description": "total expected precipitation for the day" "description": "total expected precipitation for the day"
}, },
"code": { "weatherCode": {
"type": "string", "type": "string",
"description": "weather code (sunny / cloudy / ...)" "description": "weather code (sunny / cloudy / ...)"
} }
@ -119,4 +119,5 @@ eventually, together with the current level of implementation
| ---------------------------------------------------- | ------ | ---------------------------------------- | | ---------------------------------------------------- | ------ | ---------------------------------------- |
| [iLMeteo](https://www.ilmeteo.it) | 🚧 | Weather Code not working | | [iLMeteo](https://www.ilmeteo.it) | 🚧 | Weather Code not working |
| [3Bmeteo](https://www.3bmeteo.com/) | 🚧 | Precipitation might not work as intended | | [3Bmeteo](https://www.3bmeteo.com/) | 🚧 | Precipitation might not work as intended |
| [OpenMeteo](https://open-meteo.com/) | 🚧 | Weather Code are given in WMO Code |
| [Meteo Aeronautica Militare](http://www.meteoam.it/) | ⛔️ | | | [Meteo Aeronautica Militare](http://www.meteoam.it/) | ⛔️ | |

@ -3,6 +3,7 @@ import puppeteer from 'puppeteer'
import fetchILMeteo from './scrapers/iLMeteo.js' import fetchILMeteo from './scrapers/iLMeteo.js'
import fetch3Bmeteo from './scrapers/3Bmeteo.js' import fetch3Bmeteo from './scrapers/3Bmeteo.js'
import fetchOpenMeteo from './scrapers/OpenMeteo.js'
const NIX_OPS = { const NIX_OPS = {
executablePath: process.env.NIX_CHROMIUM_PATH, executablePath: process.env.NIX_CHROMIUM_PATH,
@ -12,9 +13,10 @@ const opts = process.env.ON_NIX ? NIX_OPS : {}
const run = async () => { const run = async () => {
const browser = await puppeteer.launch(opts) const browser = await puppeteer.launch(opts)
const [iLMeteo, treBmeteo] = await Promise.all([ const [iLMeteo, treBmeteo, openMeteo] = await Promise.all([
fetchILMeteo(browser), fetchILMeteo(browser),
fetch3Bmeteo(browser), fetch3Bmeteo(browser),
fetchOpenMeteo(),
]) ])
await browser.close() await browser.close()
@ -22,8 +24,9 @@ const run = async () => {
return { return {
iLMeteo, iLMeteo,
treBmeteo, treBmeteo,
openMeteo,
} }
} }
console.dir(await run(), { depth: null }) const result = await run()
// await run() console.dir(result, { depth: null })

@ -9,6 +9,15 @@ const parsePrec = el => {
return parseFloat(text) return parseFloat(text)
} }
const getStartTime = isToday => {
if (!isToday) return 0
const d = new Date()
const h = d.getHours()
if (d.getMinutes() > 30) return h + 1
return h
}
const scrapePage = async (browser, url, isToday) => { const scrapePage = async (browser, url, isToday) => {
let result = {} let result = {}
@ -20,7 +29,8 @@ const scrapePage = async (browser, url, isToday) => {
.waitHandle() .waitHandle()
const rows = await tablePrevisioni.$$('.row-table.noPad') const rows = await tablePrevisioni.$$('.row-table.noPad')
const startTime = isToday ? new Date().getHours() : 0 // const startTime = getStartTime(isToday)
const startTime = isToday ? new Date().getHours() + 1 : 0
const endTime = 23 const endTime = 23
for (let i = startTime; i <= endTime; i++) { for (let i = startTime; i <= endTime; i++) {
@ -30,14 +40,30 @@ const scrapePage = async (browser, url, isToday) => {
const [rowLeft, rowRight] = await row.$$(':scope > div') const [rowLeft, rowRight] = await row.$$(':scope > div')
const codeDiv = (await (await rowLeft.$('.row-table')).$$('div'))[2] const codeDiv = (await (await rowLeft.$('.row-table')).$$('div'))[2]
const [tempDiv, precDiv] = await ( const rightFields = await (await rowRight.$('.row-table')).$$('div')
await rowRight.$('.row-table') const tempDiv = rightFields[0]
).$$('div') const precDiv = rightFields[1]
const appTempDiv = rightFields[4]
const code = await codeDiv.evaluate(el => el.textContent.trim())
const temp = await (await tempDiv.$('span')).evaluate(parseTemp) const weatherCode = await codeDiv.evaluate(el =>
const prec = await (await precDiv.$('span')).evaluate(parsePrec) el.textContent.trim(),
result[i] = { temp, prec, code } )
const temperature = await (
await tempDiv.$('span')
).evaluate(parseTemp)
const precipitation = await (
await precDiv.$('span')
).evaluate(parsePrec)
const apparentTemperature = await (
await appTempDiv.$('span')
).evaluate(parseTemp)
result[i] = {
temperature,
precipitation,
apparentTemperature,
weatherCode,
}
} catch (error) { } catch (error) {
result[i] = null result[i] = null
console.log(error) console.log(error)
@ -50,18 +76,31 @@ const scrapePage = async (browser, url, isToday) => {
} }
const getDaySummary = day => { const getDaySummary = day => {
let minTemp = Number.MAX_VALUE let minimumTemperature = Number.MAX_VALUE
let maxTemp = Number.MIN_VALUE let maximumTemperature = Number.MIN_VALUE
let totPrec = 0 let minimumApparentTemperature = Number.MAX_VALUE
let maximumApparentTemperature = Number.MIN_VALUE
let precipitationSum = 0
for (const h in day) { for (const h in day) {
minTemp = Math.min(minTemp, day[h].temp) minimumTemperature = Math.min(minimumTemperature, day[h]?.temperature)
maxTemp = Math.max(maxTemp, day[h].temp) maximumTemperature = Math.max(maximumTemperature, day[h]?.temperature)
totPrec += day[h].prec minimumApparentTemperature = Math.min(
minimumApparentTemperature,
day[h]?.apparentTemperature,
)
maximumApparentTemperature = Math.max(
maximumApparentTemperature,
day[h]?.apparentTemperature,
)
precipitationSum += day[h]?.precipitation
} }
return { return {
minTemp, minimumTemperature,
maxTemp, maximumTemperature,
totPrec, minimumApparentTemperature,
maximumApparentTemperature,
precipitationSum,
weatherCode: null,
} }
} }
@ -82,6 +121,6 @@ export default async browser => {
today: results[0], today: results[0],
tomorrow: results[1], tomorrow: results[1],
dayAfterTomorrow: results[2], dayAfterTomorrow: results[2],
week: results.map(getDaySummary), week: { ...results.map(getDaySummary) },
} }
} }

@ -0,0 +1,71 @@
const getDailyData = async () => {
const response = await fetch(
'https://api.open-meteo.com/v1/forecast?latitude=43.7085&longitude=10.4036&hourly=temperature_2m,relative_humidity_2m,apparent_temperature,precipitation,weather_code&timezone=Europe%2FBerlin&forecast_days=3',
)
const body = await response.json()
let today = {}
const startTime = new Date().getHours() + 1
for (let i = startTime; i <= 23; i++) {
today[i] = {
temperature: body.hourly.temperature_2m[i],
precipitation: body.hourly.precipitation[i],
apparentTemperature: body.hourly.apparent_temperature[i],
weatherCode: body.hourly.weather_code[i],
}
}
let tomorrow = {}
for (let i = 0; i <= 23; i++) {
tomorrow[i] = {
temperature: body.hourly.temperature_2m[24 + i],
precipitation: body.hourly.precipitation[24 + i],
apparentTemperature: body.hourly.apparent_temperature[24 + i],
weatherCode: body.hourly.weather_code[24 + i],
}
}
let dayAfterTomorrow = {}
for (let i = 0; i <= 23; i++) {
dayAfterTomorrow[i] = {
temperature: body.hourly.temperature_2m[48 + i],
precipitation: body.hourly.precipitation[48 + i],
apparentTemperature: body.hourly.apparent_temperature[48 + i],
weatherCode: body.hourly.weather_code[48 + i],
}
}
return {
today,
tomorrow,
dayAfterTomorrow,
}
}
const getWeekData = async () => {
const response = await fetch(
'https://api.open-meteo.com/v1/forecast?latitude=43.7085&longitude=10.4036&daily=weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,precipitation_sum&timezone=Europe%2FBerlin',
)
const body = await response.json()
let week = {}
for (let i = 0; i < 6; i++) {
week[i] = {
minimumTemperature: body.daily.temperature_2m_min[i],
maximumTemperature: body.daily.temperature_2m_max[i],
minimumApparentTemperature: body.daily.apparent_temperature_min[i],
maximumApparentTemperature: body.daily.apparent_temperature_max[i],
precipitationSum: body.daily.precipitation_sum[i],
weatherCode: body.daily.weather_code[i],
}
}
return week
}
export default async () => {
const [daily, week] = await Promise.all([getDailyData(), getWeekData()])
return {
...daily,
week,
}
}

@ -22,9 +22,14 @@ const scrapePage = async (browser, url, isToday) => {
try { try {
const row = await weatherTable.$$('.latest_detection') const row = await weatherTable.$$('.latest_detection')
const fields = await row[1]?.$$('td') const fields = await row[1]?.$$('td')
const temp = await fields[2].evaluate(parseTemp) const temperature = await fields[2].evaluate(parseTemp)
const prec = await fields[3].evaluate(parsePrec) const precipitation = await fields[3].evaluate(parsePrec)
result[startTime - 1] = { temp, prec, code: null } result[startTime - 1] = {
temperature,
precipitation,
apparentTemperature: null,
weatherCode: null,
}
} catch (error) { } catch (error) {
result[startTime - 1] = null result[startTime - 1] = null
// console.log(error) // console.log(error)
@ -38,9 +43,15 @@ const scrapePage = async (browser, url, isToday) => {
const fields = await weatherTable.$$(selector) const fields = await weatherTable.$$(selector)
const temp = await fields[2].evaluate(parseTemp) const temperature = await fields[2].evaluate(parseTemp)
const prec = await fields[3].evaluate(parsePrec) const precipitation = await fields[3].evaluate(parsePrec)
result[i] = { temp, prec, code: null } const apparentTemperature = await fields[6].evaluate(parseTemp)
result[i] = {
temperature,
precipitation,
apparentTemperature,
weatherCode: null,
}
} catch (error) { } catch (error) {
result[i] = null result[i] = null
// console.log(error) // console.log(error)
@ -64,18 +75,31 @@ const rearrangeResults = results => {
} }
const getDaySummary = day => { const getDaySummary = day => {
let minTemp = Number.MAX_VALUE let minimumTemperature = Number.MAX_VALUE
let maxTemp = Number.MIN_VALUE let maximumTemperature = Number.MIN_VALUE
let totPrec = 0 let minimumApparentTemperature = Number.MAX_VALUE
let maximumApparentTemperature = Number.MIN_VALUE
let precipitationSum = 0
for (const h in day) { for (const h in day) {
minTemp = Math.min(minTemp, day[h].temp) minimumTemperature = Math.min(minimumTemperature, day[h]?.temperature)
maxTemp = Math.max(maxTemp, day[h].temp) maximumTemperature = Math.max(maximumTemperature, day[h]?.temperature)
totPrec += day[h].prec minimumApparentTemperature = Math.min(
minimumApparentTemperature,
day[h]?.apparentTemperature,
)
maximumApparentTemperature = Math.max(
maximumApparentTemperature,
day[h]?.apparentTemperature,
)
precipitationSum += day[h]?.precipitation
} }
return { return {
minTemp, minimumTemperature,
maxTemp, maximumTemperature,
totPrec, minimumApparentTemperature,
maximumApparentTemperature,
precipitationSum,
weatherCode: null,
} }
} }
@ -98,6 +122,6 @@ export default async browser => {
today: results[0], today: results[0],
tomorrow: results[1], tomorrow: results[1],
dayAfterTomorrow: results[2], dayAfterTomorrow: results[2],
week: results.map(getDaySummary), week: { ...results.map(getDaySummary) },
} }
} }

Loading…
Cancel
Save