travopti/backend/models/handleClimateUpdate.js

90 lines
3.6 KiB
JavaScript

const axios = require('axios')
const _ = require('lodash')
// TODO: Automatically retrieve dates via aviable Data and get rid of random dates
const rangeStartDate = '2019-01' // If no date is given, this date will be used as startDate
const rangeEndDate = '2020-05'// If no date is given, this date will be used as endDate
// TODO: call method periodically, not over API
module.exports = async (dbConn, startDate = rangeStartDate, endDate = rangeEndDate) => {
console.log('update climate with:', startDate, endDate);
const result = await dbConn.query(`SELECT * FROM regions WHERE meteostat_id IS NOT NULL`)
const climateObject = await Promise.all(result.map(src => {
return createClimateObjectFrom(src, startDate, endDate)
}))
const climateObjectArr = climateObject.reduce((total, element) => total.concat(element), [])
await writeToDatabase(dbConn, climateObjectArr)
const res = `region_climate update complete. see backend logs for info.`
return res
}
async function createClimateObjectFrom(src, startDate, endDate) {
let res
if (src.meteostat_id === '') {
console.log("skipping: no meteostat id ")
return []
}
try {
res = await axios.get(`https://api.meteostat.net/v1/history/monthly?station=${src.meteostat_id}&start=${startDate}&end=${endDate}&key=${process.env.METEOSTAT_API_KEY}`)
} catch (error) {
console.log("error while getting data from meteostat: couldn't find results for following region: ")
console.log(src.region + " with meteostat_id " + src.meteostat_id)
console.log(error)
return []
}
if (!res.data.data) {
console.log("skipping: no data for station with meteostat_id " + src.meteostat_id + " (" + src.region + ")")
return []
}
const retVal = res.data.data.map(element => {
let result = {
region: src.region,
region_id: src.id,
year: element.month.split("-")[0],
month: element.month.split("-")[1],
temperature_mean: element.temperature_mean,
temperature_mean_min: element.temperature_mean_min,
temperature_mean_max: element.temperature_mean_max,
precipitation: element.precipitation,
rain_days: element.raindays,
sun_hours: element.sunshine,
humidity: element.humidity ? element.humidity : null
}
//console.log(result)
return result
})
return retVal
}
async function writeToDatabase(dbConn, climateObjArr) {
for (const element of climateObjArr) {
//console.log(element)
try {
await dbConn.query(`
INSERT INTO region_climate
(region_id, year, month, temperature_mean, temperature_mean_min, temperature_mean_max, precipitation, sun_hours, humidity, rain_days)
VALUES (${element.region_id}, ${element.year}, ${element.month}, ${element.temperature_mean}, ${element.temperature_mean_min}, ${element.temperature_mean_max}, ${element.precipitation}, ${element.sun_hours}, ${element.humidity}, ${element.rain_days})
ON DUPLICATE KEY UPDATE
temperature_mean = ${element.temperature_mean},
temperature_mean_min = ${element.temperature_mean_min},
temperature_mean_max = ${element.temperature_mean_max},
precipitation = ${element.precipitation},
sun_hours = ${element.sun_hours},
humidity = ${element.humidity},
rain_days = ${element.rain_days};`)
} catch (error) {
if (error.code !== 'ER_DUP_ENTRY') {
console.log("element which causes problems: ")
console.log(element)
console.log("query which causes problems: ")
console.log(error)
} else {
console.log(element.region + ": " + error.sqlMessage)
}
}
}
};